home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
win
/
steph1b0.zip
/
STEPH.DOC
< prev
next >
Wrap
Text File
|
1994-10-30
|
188KB
|
5,468 lines
Steph
Programmers Manual
Windows and Menus user interface library for C.
Version 1.0b.
Copyright (c) 1993/1994,
by Stephen Morphet
CONTENTS.
SHAREWARE.
What is Shareware?
Rules for Steph.
INTRODUCTION.
Who is Steph?
What kind of features does Steph provide?
Why does Steph use text mode?
The Steph Libraries.
Disclaimer.
STEPH APPLICATIONS - AN OVERVIEW.
What bits does an application need?
Menus.
Windows.
Dialogue boxes and variations.
The Toolbar.
The Speed Bar.
WRITING STEPH APPLICATIONS.
DEMO.C, A sample application.
Hooks.
Initialising Steph.
Menus
Building Menus.
Attaching functions to menus.
Adding help text to menus.
Checkable items.
Grey items.
Using Menus.
Keyboard.
Mouse.
Windows
Building Windows.
The keyboard and windows.
Implementing filter and action functions.
Examples:
The mouse and windows.
Notes on using the scroll bar hooks.
A minimum program.
The keyboard at 'system level'.
Flash Boxes.
Building Dialogue Boxes.
Adding controls to Dialogue Boxes.
Frame:
Label:
Button:
Check box:
Radio buttons:
Text:
List:
Combo box:
Reading and writing the data in a dialogue.
Buttons:
Check boxes:
Radio buttons:
Text boxes:
List boxes:
Combo boxes:
Labels:
Frames:
Updating and redrawing controls.
Greyness.
Overriding a control's exit mode.
Dialogue box bars.
Dependency.
Dialogue box global keys.
Query Boxes.
Using Dialogue Boxes.
Mouse.
Keyboard.
More things to do with windows.
Opening, closing, resizing etc.
Redrawing and refreshing windows.
The window contents list.
Fixed lines.
Window redraw modes and the redraw function.
The WD_AUTO mode.
The WD_COLOUR mode.
The WD_CLEAR mode.
The WD_AUTO mode.
Colouring functions for WD_COLOUR mode.
Details of colour code storage in WD_COLOUR mode.
The Speed Bar.
Text display on the speed bar.
Adding buttons to the speed bar.
The Tool Bar.
Reserving a toolbar.
Controls on the speed bar.
Displaying text on the toolbar.
Pop up menus.
Other Steph Facilities.
The Initialise Function.
The Loop Functions.
Draggable dialogues.
Working with Lists.
Memory allocation details.
The mem_handler function.
Redefining mem_handler.
Using the mem_handler mechanism from application code.
A neater way to allocate memory.
Customising Steph.
USING STEPH IN GRAPHICS MODE.
Set the computer into graphics mode.
Call _steph_initialise with the M_GRAPHIC parameter.
Set up screen save and restore functions.
Call _steph_setupgraphic, giving details of
the screen size and pointers to the save and
restore functions.
Call _steph_go
Include code to restore the screen mode in your exit function.
REFERENCE.
User Functions.
Setup And Go Functions.
Window Build Functions.
Menu Build Functions.
Dialogue Box And Control Build Functions.
Miscellaneous Build Functions.
Dialogue, Flash and Query Boxes.
Menu Functions.
Window Functions.
Window Buffer Functions.
Window Colour Code Functions.
Speed Bar Functions.
Tool Bar Functions.
List functions.
Mouse And Miscellaneous Functions.
Cursor functions.
Keyboard functions.
Functions for Graphics Modes.
Popup Menu Functions.
Selected System Variables.
General system variables.
Window variables.
Menu variables.
Dialogue box, query and flash box variables.
Speed bar variables.
Tool bar variables.
Graphics mode variables.
SHAREWARE.
What is Shareware?
Shareware is an alternative to the usual way
of distributing software. With Shareware
you can try out software before paying for
it. The software that you wish to evaluate
is made available to you for free, or for a
small charge that covers only the cost of
the disk and copying process. When you have
used the software for a reasonable period,
typically 30 days, you are expected to
decide whether you wish to continue using
it. If you do, then you should register the
software by sending payment directly to the
author(s) according to the instructions that
come with the software. Depending on the
software, one or more incentives may be
offered to encourage your registration. For
example, you may receive the latest version
of the software, or a version with added
features. You may also become eligible for
technical help with the product.
Rules for Steph.
If you want to play with Steph, these are the rules:
The Steph libraries are Shareware, as described above.
If you continue to use the product after a trial period
of approximately 30 days, and you have not already
registered, you should register Steph by sending £25
(Sterling) to:
Stephen Morphet,
49 Meadowfield Road,
Stocksfield,
Northumberland.
ENGLAND.
NE43 7PZ.
Registered users become eligible for peace of mind, and
assistance with Steph by letter or E-Mail. As a
registered user you also gain the right to distribute
programs that you write with Steph. A printed copy of
this manual will be supplied if requested.
INTRODUCTION.
Who is Steph?
Steph is a library of C functions for C programmers.
She is designed to make it easy to create attractive text
mode MSDOS applications for the IBM PC and compatibles.
Steph allows these applications to take advantage of the
wide range of windowing and menuing facilities that she
provides.
Computer users these days expect software to be easy to
use, with an attractive and intuitive interface. This
is not good news for programmers who are forced to
spend more time on the look and feel of their program,
and less time on the program itself. By using a ready
made interface, like Steph, you are once again free to
concentrate on the important parts of your programs.
What kind of features does Steph provide?
Steph provides a windows and menus based interface, and
will take advantage of a mouse where one is installed.
Steph also provides dialogue boxes with a full range of
controls, pop-up menus, a toolbar and a speed bar of
buttons at the bottom of the screen.
Why does Steph use text mode?
Text mode is fast. When text mode is sufficient to
display the information from an application there is
little reason to suffer the speed penalties of using a
GUI such as Microsoft's Windows. Many people still use
DOS applications, and many programmers still develop
DOS programs.
Steph is designed to work primarily in text modes,
although a facility exists to run in graphics modes on
EGA or VGA systems. The character based environment is
retained but windows may contain pixel graphics.
You will soon notice that the 'windows' provided by
Steph are 'letter box slots.' That is to say, each
window occupies the full 80 column width of the screen
and does not overlap with neighbouring windows. In my
experience The text mode screen (80 by 25 characters,
or even larger 43 or 50 row modes) is not large enough
to use overlapping, sizeable windows efficiently.
Steph keeps the windows on the screen neatly ordered,
and the fixed width means that they are large enough to
display a useful amount of information.
The Steph Libraries.
Steph is supplied as a set of .LIB library files
to link to your C programs. Libraries are provided
for MEDIUM or LARGE memory models, and for Microsoft C
or Turbo C compilers.
The Microsoft libraries have been tested with Microsoft
C/C++ 7.0 and Microsoft QuickC 2.5. The Turbo C libraries
have been tested with Turbo C++ 3 for DOS, and also seem
to work with Borland C++ 3.0.
Library Memory Model Complier
STEPH_M Medium Microsoft C
STEPH_L Large Microsoft C
TSTEPH_M Medium Turbo C
TSTEPH_L Large Turbo C
Linking to a Steph library will add about 100K to the
size of your executables. This figure is affected by
your choice of memory model, and the use that your
program makes of Steph's features.
The header file STEPH.H should be #include'd at the
beginning of any source file that requires access to
any of Steph's functions or data.
Disclaimer.
I can accept no liability of any kind, including loss
or damage of any sort to hardware, software, or data
that comes about through the use of, or inability to
use any of the Steph libraries or any program created
from them.
STEPH APPLICATIONS - AN OVERVIEW.
What bits does an application need?
Steph applications can be thought to consist of four
major elements:
1) Menus.
2) Windows.
3) Dialogue boxes and other pop up windows.
4) Code specific to the application.
The first three of these elements are looked after by
Steph, and are concerned with the user interface to the
program. The fourth is the application itself, and is
the responsibility of the programmer.
Menus.
Steph's menus appear at the top of the screen as a
number of main headings on a menu bar. The menus can
be pulled down with the mouse or keyboard causing a
number of options to appear. A further selection may
be made from these options.
Pop up menus can appear anywhere on the screen, and are
similar in operation to the main menus.
Windows.
Windows fill the majority of the screen and are used to
display data - for example one window may contain text
in an editor, while another displays program output.
One window, the main window, always exists. Further
windows can be added above or below it. Windows can be
resized, maximised, minimised and closed with the
mouse. They may also have scroll bars for navigation
through the data.
Dialogue boxes and variations.
Dialogue boxes are used for communication with the
program. They can contain controls such as text entry
fields, buttons, lists and check boxes. They can be
operated by mouse and keyboard.
Query boxes are a special variation on dialogue boxes.
A query box is used for example, to ask a simple
question, where the response might be 'yes' or 'no', or
perhaps the infamous 'Abort', 'Retry' or 'Fail'. The
query box contains an area of text, and a number of
option buttons.
A further variation is the Flash box. This is a
dialogue box with no controls and is used to display
information in a non-interactive manner. For example,
a flash box might display the text, 'Thinking...' while
the processor is busy.
The Toolbar.
The toolbar is an area at the top of the screen, below
the menu bar, which can display a number of controls
including buttons and combo boxes. A toolbar is often
seen, for example, in a word processor, where commonly
used formatting options are available.
The Speed Bar.
The Speed Bar is the bottom row of the screen. It is
often used to display a set of possible current options
in the form of a set of buttons. The Speed Bar is also
used to display helpful information when a dialogue
box, query box or menu is active.
WRITING STEPH APPLICATIONS.
DEMO.C, A sample application.
A sample application is provided in the file DEMO.C.
The program does not perform any useful tasks: It
simply demonstrates many of the functions described
below.
Hooks.
Hooks are the way to attach your own code to your Steph
programs. For example, each menu option has an
associated function hook. A function attached to this
hook will be executed when that menu option is
selected. Similarly there are hooks on window controls,
and on dialogue box controls.
A function to be attached to a hook can accept no
parameters, nor can a value be returned. Functions to
be attached to hooks should therefore have prototypes
as follows:
void my_function( void );
The type vfnptr is defined in STEPH.H to describe a
pointer to such a function. For example:
vfnptr p_function;
p_function = my_function;
To attach such a function to a hook, a pointer to the
function is generally passed as a parameter to one of
the 'build' functions supplied in Steph's library. (Of
course, there is usually no need to assign the pointer
to an intermediate variable, as above.) Steph will
hang the function on the hook for you.
Information can be passed to and from these functions
by means of global variables if that is necessary.
Certain hook functions will need to make use of
relevant data that is stored in global variables by
Steph.
Initialising Steph.
Steph is initialised by calling the _steph_initialise
function:
if( !_steph_initialise( gmode ) )
{
printf( "Steph couldn't start in the current
screen mode." );
exit(0);
}
Where gmode specifies the screen mode type: M_TEXT or
M_GRAPHIC. We will assume M_TEXT for the time being.
Graphics modes are discussed in due course.
When this function has returned TRUE, Steph is ready to
be set up for use. Steph starts up in the current
video mode, which should be either mode 2 or 3, for
colour text, or mode 7 on monochrome systems. You may
wish to set the screen mode before calling
_steph_initialise. If you want to set EGA and VGA
systems into 43 or 50 line modes you should also do
this before calling _steph_initialise.
If an application is written with sufficient
consideration given to the size of dialogue boxes,
menus and other screen elements, it will be able to
adapt automatically to the number of screen rows in
use.
Menus
Building Menus.
When a menu structure has been decided upon it is
defined using the _menu_build function as follows:
_menu_build( 0, /* menu number */
"&Moo", /* title text */
"&Oink", /* list of pull down items */
"=",
"Ba&a",
"Snu&ffle",
NULL ); /* list terminator */
The first parameter is the menu code number. This
number identifies the menu and should be between 0 and
15.
The second parameter is the text for the menu heading
which will appear on the top row of the screen. The
Ampersand (&) does not appear but is used to specify
which character is the hotkey for this menu. In this
case it is the 'M' as this is the character that
appears immediately after the '&'. Note that a text
need not contain an ampersand, in which case no hotkey
will be assigned.
The following parameters specify the texts that will
appear in the pull down menu below the 'Moo' heading.
The NULL is used to terminate the list. This menu
therefore has four pull down options: 'Oink', '=',
'Baa', and 'Snuffle'. The second of these ('=') is
special, indicating a horizontal bar across the menu at
this point, and does not actually appear as an '='
sign. A normal menu item may not begin with the '='
character.
Menus will appear from left to right along the menu bar
in the order that they are built. A menu can be made
to appear on the right of the menu bar by prefixing the
menu title with the caret character '^'. For example:
_menu_build( 1,
"^&Squeak",
"S&quelch",
"&Snort",
"&Tickle",
NULL );
Would create a menu titled 'Squeak' at the right hand
side of the menu bar, with three pull down options
below it. Menus created at the right hand side of the
menu bar appear from right to left in the order in
which they were built. The caret prefix has no effect
other than in the menu title text.
The following code fragment demonstrates two further
options that can be applied to menu items:
_menu_build( 2,
"&Quack",
"$Duck&1",
"?Duck&2",
"Duck&3",
NULL );
The interesting items here are the first pull down item
"$Duck&1" and the second "?Duck&2".
The dollar sign prefix '$' is valid in title texts or
pull down item texts and indicates that the option is
'greyed out' or unavailable. If the title text is
greyed out, the menu cannot be opened. If an option
text is greyed out that option cannot be selected.
The question mark prefix '?' is valid only in pull down
item texts and indicates that the item has a check mark
displayed next to it. The item is initialised with the
check set to TRUE. A function _menu_toggle is provided
which can be hooked to such a menu option in order to
toggle the check mark when the item is selected.
A percent sign prefix '%' also indicates that a menu
item is checkable, but that the item starts without a
check mark. Menu items defined without a dollar sign
'$' or percent sign '%' cannot be checked..
It is possible to redefine a menu by calling
_menu_build again. This will overwrite any menu
currently defined with the same menu number.
Menu item numbering is as follows: Item zero is the
title item. Item one is the first pull down option
item, and numbering continues 1, 2, 3, etc. for each
option. Greyed out items and horizontal bars are
included in the numbering scheme, although they cannot
be selected.
Attaching functions to menus.
A function hook is provided for each of the pull down
options in a menu. Functions are attached by means of
the _menu_functions function:
_menu_build( 1,
"&Quack",
"$Duck&1",
"?Duck&2",
"Duck&3",
NULL );
_menu_functions( 1, /* menu code number */
NOFN, /* no function */
_menu_toggle, /* the toggle function */
function1 ); /* a user function */
The example above shows functions attached to the
three options "Duck1", "Duck2" and "Duck3" in the
"Quack" menu. The function attached to "Duck1" is the
constant NOFN, indicating that in this case, no
function is attached. This is the default for all
options as soon as they are built. The _menu_toggle
function is attached to the option "Duck2". Note that
"Duck2" was specified with a check mark in the
_menu_build call. _menu_toggle is used to change the
state of the check mark whenever the option is
selected. The final option "Duck3" has a function
function1 attached. This specifies that one of your
own functions is to be used here. function1 should be
defined elsewhere as:
void function1( void );
Adding help text to menus.
A text appears on the speed bar at the bottom of the
screen to give further information about the currently
selected menu item. These texts are set using
_menu_helptext:
_menu_helptext( number,
"Help for the title item.",
"Help for the first pull down item.",
"Second pull down item.",
"And the third." );
Texts should be supplied for the main title item and
for each pull down option. You should replace a string
with NOTEXT if you want no text to be displayed for
that option.
Checkable items.
When a menu item is defined using the '$' or '%'
prefixes it is a checkable item. When the check is
TRUE a tick or mark will be displayed in the menu
before the item text. When the check is FALSE there
will be nothing displayed, although these characters
can be redefined, for example to show a tick and a
cross.
As described above, a checkable item can be toggled by
attaching the _menu_toggle function to the item. This
function will automatically toggle the check mark on
the most recently selected menu item. If there is
already another function attached to the hook you could
call _menu_toggle from inside that function.
When you wish to change a check mark at a time other
than immediately after that menu item has been selected
you should use the _menu_check function, where the menu
and item numbers must be specified:
_menu_check( menu_number, item_number, check );
Check can be one of the constants CHECKON or CHECKOFF
which set the check to TRUE or FALSE respectively, or
CHECKTOGGLE which will change the state of the check
mark regardless of its current state.
To determine the state of a checkable item, use the
following function:
state = _menu_get_check( menu_number,
item_number );
This function will return CHECKON, CHECKOFF, or NOCHECK
if the item is not checkable.
Grey items.
When a menu title or option item is set to be 'greyed
out' it becomes impossible to select that item. This
is useful to prevent the user making selections that
are not appropriate at that time. Items are set to be
grey by prefixing the menu text with the dollar '$'
character in the call to _menu_build.
The state of a menu items greyness can be controlled
using the _menu_enable function.
previous_state = _menu_enable( menu_number,
item_number, state );
Where the menu number is the menu index used in
_menu_build, and the item number specifies the option
for which the greyness is to be altered. In the item
number zero specifies the main menu title, and options
are numbered from one upwards. The state code passed
should be either of the constants ENABLED or DISABLED.
The code returned by the function will also be one of
these.
Using Menus.
Keyboard.
The menus are activated by pressing the ALT key. A
highlight appears on the menu bar over the text for
menu zero. The highlight can be moved between menus
with the cursor left and right keys. Pressing one of
the highlighted hotkeys will cause the associated menu
to be opened. Pressing cursor up, cursor down, space or
enter will cause the highlighted menu to be opened (if
it is not greyed out), and the highlight will move to
the first option.
The up and down cursor keys now serve to highlight
options from the menu. The cursor wraps around from
top to bottom, and skips over horizontal bars. Items
can be selected with the enter key or space bar,
provided they are not greyed out. Pressing left and
right cursor keys at this stage opens the menu to the
left or right of the current menu. Pressing a
highlighted hotkey selects an item.
Once an item is selected the menu is closed and the
attached function for the selection is called.
You can exit from the menus at any point by pressing
ESC or ALT.
Mouse.
The menus can be activated by clicking on one of the
texts on the menu bar with the mouse. The menu is
opened, and the mouse can be used to drag the highlight
bar to an option, by holding down the button, in which
case the option will be selected when the button is
released. Alternatively, the button can be released
over the title text, in which case the menu remains
open and an option can be selected by clicking it once.
Other menus can be opened by clicking the title with
the mouse, in which case the current menu is closed.
Note that you can switch between mouse and keyboard
operation at any stage.
Windows
Building Windows.
Windows are created with the _window_build function:
_window_build( number, position, height, "The
Title", filter, keyaction, mouseaction );
The number is used to identify the window. The first
window built should be the main window, which is always
window zero. For example:
_window_build( 0, WP_MAIN, 0, "Main Window", NOFN,
NOFN, NOFN );
The height parameter for the main window has no effect,
since the main window always expands to fill the space
unused by other windows. It has been set to zero here.
The main window is always created with horizontal and
vertical scroll bars, and a maximise button. The three
function hooks are used to define the way in which the
window responds to keyboard and mouse, and will be
described later.
Subsequent windows are defined in a similar way, using
_window_build. They should be given positions WP_TOP
or WP_BOT. One restriction exists in that all windows
must be given consecutive numbers, as an undefined
window will be treated as the end of the list. The
second restriction is that windows defined as 'top
windows' with WP_TOP must appear BEFORE any WP_BOT
windows in the list. Any window listed after the first
occurrence of a WP_BOT window will be treated as a
'bottom window' regardless of the position value
assigned to it.
The following example defines five windows:
_window_build( 0, WP_MAIN, 0, "0 The Title",
NOFN, NOFN,
NOFN );
_window_build( 1, WP_TOP, 2, "1 Topper than
that", NOFN,
NOFN, NOFN );
_window_build( 2, WP_TOP, 2, "2 Top Window",
NOFN, NOFN,
NOFN );
_window_build( 3, WP_BOT, 3, "3 Bottom Window"
NOFN, NOFN,
NOFN );
_window_build( 4, WP_BOT, 3, "4 Nearly the
bottom", NOFN,
NOFN, NOFN );
Note that window zero is the main window. It is
followed by the two top windows, and finally two bottom
windows. The title is displayed on the top border of
the window when it is displayed on screen.
Top windows 'hang' from the top of the screen with
lower numbered windows highest up. The bottom windows
'pile up' at the bottom of the screen with lower
numbers lower down. The height parameter is used to
set the initial height of the top and bottom windows.
The height refers to the number of rows inside the
window, excluding the 'frame' or border.
Windows are created with a default set of controls:
Each window has both horizontal and vertical scroll
bars, a close button (except the main window, which
cannot be closed) and a maximise button which changes
to a minimise button as appropriate.
You can change the controls present on a window using
the function _window_controls:
_window_controls( window, controls );
Where window is the number of the window to alter, and
controls is a byte indicating which controls are to be
used. There are a number of constants which can be
used:
WC_CLOSE A close button.
WC_MAX A maximise button.
WC_MIN A minimise button.
WC_HSCROLL Horizontal scroll bar.
WC_VSCROLL Vertical scroll bar.
These can be combined with C's bitwise OR operator '|'
For example:
_window_controls( 1, WC_CLOSE | WC_MAX );
This would give window one close and maximise buttons,
and turn off all others.
If you attempt to give the main window a close button
it will have no effect. Similarly maximise buttons
will be ignored on windows that are currently maximised
(these display a minimise button) and minimise buttons
are ignored on windows that are not maximised. If you
do not know whether a window is maximised, or cannot be
bothered to find out, it is safe to attempt to set both
buttons and Steph will add the appropriate one, e.g.:
_window_controls( 1, WC_CLOSE | WC_MAX | WC_MIN |
WC_VSCROLL | WC_HSCROLL );
This line effectively sets the controls options to the
defaults for a top or bottom window.
The keyboard and windows.
The behaviour of each window is dependant on the
application. It will be required to respond to certain
keystrokes and ignore others. Two of the three
function hooks specified in _window_build can be used
to specify this behaviour.
Each window can have a filter function and a keyboard
action function attached via hooks. When Steph detects
a keystroke that is not intercepted at the system level
(see the discussion of system level keystrokes later)
it is passed to the filter function for the current
active window. This filter decides if the keystroke is
to be used or discarded, and if it is to be used, Steph
will call the keyboard action function to act upon it.
Implementing filter and action functions.
The default filter is implemented by leaving the filter
function pointing to NOFN. The default filter passes
the cursor keys and alphanumeric keys (those with ASCII
codes in the range 32 to 126). For most situations,
where this selection is inappropriate, the user must
write their own filter, as follows:
The filter must have the same prototype as for any
hooked function:
void filter_function( void );
It can therefore accept no parameters. The keystroke
should be read from the global variable _window_spec:
_window_spec.key1
_window_spec.key2
One or the other of these values will be zero.
Normally key1 will contain the ASCII code of the key
pressed, and key2 will be zero. When key1 is zero,
key2 contains the extended code, such as is generated
by the getch function when a cursor key, for example,
is pressed.
From the information in key1 and key2 the decision as
to whether the keystroke must be passed can be made.
If the key is to be passed, the key1 and key2 variables
should be left unchanged and the function exited. If
the key is not to be passed, then both key1 and key2
should be set to zero, before exiting the function.
When the filter passes a keystroke the keyboard action
function for the window is called, provided that one
has been defined. There is no default function in this
case. The keyboard action function should also read
the key1 and key2 variables in _window_spec in order to
determine the action to be taken.
Examples:
1) If a window accepts no input, the keyboard action
function will be NOFN. It is also unnecessary to
provide a filter (i.e. you can set it to NOFN, for the
default filter) since Steph will not bother to filter
keystrokes if she sees that there is no keyboard action
function.
2) A text editor in a window would require that almost
all keystrokes were passed. A user defined filter
function is required. The keyboard action function
can then perform the editing operations, such as
inserting text, moving around with cursor keys, etc.
The third function pointer passed to _window_build is
called mouseaction. It is reserved for use in future
versions of Steph and should be set to NOFN every
time. Functions attached to this hook will never be
called by this version of Steph.
The mouse and windows.
Steph handles many of the basic mouse/window
interactions such as resizing, closing, maximising, and
scroll bar use. However, a hook is provided at each of
the following mouse/window events:
Buttons and resizing.
close - Called when the close button is
pressed.
max - Called when the maximise button is
pressed.
min - Called when the minimise button is
pressed.
size - Called when the title bar is dragged
to resize the window.
Vertical scroll bar actions.
vup - Called when the scroll bar up arrow
is clicked.
vdown - Called when the scroll bar down
arrow is clicked.
vdrag - Called when the scroll bar's blip is
dragged.
vpup - Called when the scroll bar is
clicked above the blip.
vpdown - Called when the scroll bar is
clicked below the blip.
Horizontal scroll bar actions.
hup - Called when the scroll bar up arrow
is clicked.
hdown - Called when the scroll bar down
arrow is clicked.
hdrag - Called when the scroll bar's blip is
dragged.
hpup - Called when the scroll bar is
clicked above the blip.
hpdown - Called when the scroll bar is
clicked below the blip.
Selection functions.
unselect - Called for the previous active
window when the active window is changed
by a mouse action.
select - Called when the window becomes
active due to a mouse action, or when the
window is clicked over the window 'pane'.
Activation function.
activate - This hook is called when a window
becomes active as a result of a mouse
action taking place on another window. At
present, this occurs only when another
window is closed, and the window below it
becomes active.
These seventeen function hooks are set using the
function _window_mouse_functions which has the
following form:
void _window_mouse_functions( window_number,
close,
max, min, size, vup, vdown, vdrag, vpup,
vpdown,
hup, hdown, hdrag, hpup, hpdown, unselect,
select,
activate );
The mouse buttons which cause these events are, by
default, that either button can cause a 'select' event,
and the left button must be used to operate any of the
controls. These defaults can be changed by setting the
_window_spec.mousecode and _window_spec.mousecontrol.
The mousecode variable indicates the set of buttons
which will cause a 'select' event. The mousecontrol
variable indicates which button will cause a control to
operate, with the restriction that it must be a subset
of the set defined by mousecode.
The window_number parameter specifies the window to
which these functions are to be attached. The
following sixteen parameters are the function pointers,
which may be set to NOFN if no code is to be attached
to a particular hook.
Note that these functions are only called when a mouse
event occurs on a window. If windows are closed,
maximised, etc. by another part of the program they are
not called. It is the task of the programmer to
maintain consistency in the behaviour of the program if
there exist multiple methods of, for example, closing a
window.
Notes on using the scroll bar hooks.
When a scroll bar event occurs, Steph runs the
appropriate function as defined in
_window_mouse_functions . This function is responsible
for updating the scroll 'blip' positions stored in
_window[].vsblip and _window[].hsblip. Steph does not
alter these values automatically, as the programmer may
wish to change the behaviour of the scroll bar to suit
the application. When a scroll bar 'drag' event has
occurred the new blip position is made available in
_window_spec.scrinfo for use by the handler function.
Use of the scroll bars is demonstrated in the EDITOR.C
example program.
A minimum program.
The information presented so far, on menus and windows,
is sufficient to write the most basic of programs:
A minimum program must perform a number of 'setup'
steps before it can be started:
1) Initialise Steph, having chosen the screen mode if
necessary.
2) Build at least one menu.
3) Build the main window, and any others that are
required.
4) Issue the function call: _steph_go(); to begin.
Note that Steph provides no means of exiting the
program. The user must provide a function, perhaps
attached to an 'Exit' menu option to perform the
following:
1) Issue the function call _steph_closedown();
2) Exit the program. e.g. exit( 0 );
Note that the program must exit after _steph_closedown
has been called. Steph will behave unpredictably if
the user function is allowed to return and Steph is
allowed to continue running after the closedown
function has been called.
You will now know enough to get a simple application
working with Steph. There are however, a large number
of further features which add greatly to Steph's
capabilities, and should be taken advantage of in order
to create a polished application. These features are
described in the following sections.
The keyboard at 'system level'.
It has been described above how a filter and action
function can be attached to each window in order to
handle keystrokes. It is also possible to add a global,
or so called 'system level' keyboard filter and action
function, which will have a look at each keystroke and
steal it from the active window if it is passed by the
filter. This facility might be used, for example, if
you wanted to use the F6 key to move the focus to the
next window on the screen. This action occurs
regardless of the currently active window, and so
should be handled at system level.
To set the filter and action functions use the
function:
_window_setsyskey( filter_function,
action_function );
Where filter_function and action_function are pointers
to functions of the type:
void function( void );
The action of the filter function differs slightly to
those used for keystrokes in windows. The keystrokes
are made available in _window_spec.key1 and
_window_spec.key2 as before, but in order to indicate
that the keystroke has been grabbed at the system
level, the variable _window_spec.syskeyflag should be
set to TRUE. If the key is not to be passed by the
system key filter _window_spec.syskeyflag should be set
to FALSE.
The values in _window_spec.key1 and _window_spec.key2
should not be altered because Steph still has to pass
the keystrokes to the filter function for the active
window. If the key values are changed then the new
values will be passed on to the active window.
If the keystroke is passed by the filter, the action
function will be called, and the keystroke will not be
made available to the active window's filter function.
Flash Boxes.
Flash boxes are used to display information on the
screen in a non-interactive manner. Typical uses might
be to display status or error messages as a program
executes. Interactive messages are provided for with
Query Boxes (see later).
A flash box is displayed with the function:
_flash_box( position, textlist );
The position variable can be either DB_CENSCR to centre
the flash box on the screen, or DB_CENWIN to centre
the flash box over the active window. Flash boxes
cannot be given absolute positions.
The variable textlist is a pointer to a dynamically
allocated list, as is created by the function
_s_buildlist . The items in this list are the lines
of text to be displayed in the flash box. For example:
_flash_box( DB_CENSCR, _s_buildlist(
"The top line\0The second line.\0" );
would display the texts, 'The top line' and 'The second
line' in the flash box.
Steph provides a number of functions for working with
lists. These are described in another part of this manual.
If a flash box is already on the screen it will be
removed, and the new one drawn in its place. The last
flash box on the screen can be removed with:
_flash_box_remove();
Building Dialogue Boxes.
A dialogue box is an interactive form-like control that
takes information from the user. Flash boxes and query
boxes (which are discussed later) are in fact derived
from the more sophisticated dialogue box. The dialogue
box has a number of controls, each of which may be one
of a number of types:
FrameA non interactive box on the form, with title.
LabelNon interactive text, placed on the form.
ButtonPressable button, with text inside.
Check boxA box that can be 'checked', i.e. yes/no info.
Radio buttons A number of buttons, one checked at a time.
TextA box that you can enter text into.
ListAllows selection of a choice from a list.
ComboLike a pop up list.
Dialogue boxes can be built before they are needed,
typically at the beginning of the program using the
function:
_dbox_build( number, position, xsize, ysize,
controls,
title, helptext );
Where number is the number of the dialogue box, in the
same way that menus and windows are all identified by
number. The parameter position is used to specify the
way the dialogue is displayed on screen. It may take
the following values.
CENSCRCentre the dialogue on the screen.
CENWINCentre the dialogue on the current window.
ABSPOSAbsolute position.
The xsize and ysize parameters define the size of the
box, measured inside the borders. The controls
parameter specifies the number of controls which the
box will contain.
The helptext is a pointer to a string that will be
displayed on the speed bar while the dbox is on screen.
For example,
_dbox_build( 0, CENSCR, 20, 10, 2, "A sample
box.", "This is a test." );
would create dialogue box zero, centred on the screen,
twenty characters wide and ten deep, with two controls.
The dialogue would have the title "A sample box." on
its top edge, and the speed bar would display the words
"This is a test." when the dialogue was on screen.
If a dialogue box is defined with ABSPOS position, the
position of the top left corner of the box is
positioned with the function:
_dbox_setabspos( number, xpos, ypos );
Where number is the box number as set in _dbox_build(),
and xpos and ypos measure the position of the box in
characters. The top left of the screen is (1, 1).
The dialogue box is currently empty, and so cannot be
displayed. We must therefore fill it with controls.
Adding controls to Dialogue Boxes.
A function exists to add each control type to a
dialogue:
Frame:
A non interactive box, drawn on the dialogue, with
optional text centred in the top edge.
_dbox_c_frame( dbox, control, xpos, ypos, xsize,
ysize, titletext );
The dbox parameter refers to the dialogue box number
specified in _dbox_build(). Control is the number of
the control in the dialogue. The numbering of controls
dictates the tabbing order. For a dialogue with ten
controls, they will be numbered from zero to nine.
Numbers should be consecutive, as an undefined control
is treated as the end of the list.
The xpos and ypos parameters position the control
relative to the top left hand corner of the dialogue.
The top left corner of the dialogue (just inside the
border) is (1, 1).
The xsize and ysize parameters determine the size of
the frame. The title of the frame is set by the
pointer to a string, titletext. Clearly this should
not be longer than the xsize of the frame. If the
pointer is left NULL, then the frame will be untitled.
Label:
Non interactive. A label places a piece of text on the
dialogue.
_dbox_c_label( dbox, control, xpos, ypos,
labeltext );
Dbox and control are used as described above. Xpos and
ypos position the beginning of the label text relative
to the top left corner of the dialogue. Labeltext is
a pointer to a string which is the text of the label.
Button:
A button can be pressed with the mouse or keyboard. A
return value is set that can be interrogated by the
application. A function can be attached via a hook,
that will be called when the button is pressed.
_dbox_c_button( dbox, control, xpos, ypos, width,
buttontext, exitmode, function );
Dbox, control, xpos and ypos are as above. Width
defines the width of the button, i.e. the space between
the enclosing chevrons.
Buttontext is a pointer to the text that appears in the
button. It may contain an ampersand '&' to define a
hotkey, as for menu items.
The exitmode parameter determines whether the dialogue
box should be closed when the button has been pressed.
It can be set to EXIT or NOEXIT. A further constant
ESCAPE can be used. This is similar to EXIT, but it
causes the data in the dialogue to be restored to its
entry values, as if the escape key had been pressed.
Function is a pointer to a normal hooked function.
This function will be called as soon as the button is
pressed, and on return, the dialogue will examine
exitmode to determine the action to be taken.
Check box:
A check box has a title, followed by a small box in
which a check mark may or may not be displayed. The
check can be toggled by the user with the keyboard or
the mouse. Check boxes are typically used as simple
switches, where an on/off or yes/no type response is
required.
_dbox_c_check( dbox, control, xpos, ypos,
checktext, initialvalue, function );
Checktext is the title of the control. It may contain
an ampersand '&' to specify a hotkey. The box itself
appears at the end of this text.
Initialvalue can be set to TRUE or FALSE. TRUE
indicates that the checkbox starts life with a check
mark, and FALSE indicates that it begins empty, or
unchecked.
Function is a hooked function that is called when the
state of the check box is changed.
Radio buttons:
Radio buttons are like the push-button waveband
selectors on a radio. They are used when the user must
always choose one, and only one from a number of
options. When one is pressed, the previous selection
becomes deselected. Like when you press the FM button,
and the long wave button pings out!
_dbox_c_radio( dbox, control, buttonlist,
initialitem, function );
Buttonlist is a pointer to an area of dynamic memory
where a definition of the set of buttons is stored. It
must be defined using the _s_build_radiolist()
function. The list takes the form:
item 0 byte xpos
byte ypos
byte hotkey
byte alpha
byte greyness
"text"
...
item n byte xpos
byte ypos
...
"text"
The hotkey and alpha bytes are for internal use and
should be set to zero. The greyness byte will be
discussed later - we will set it to zero for now.
Example code:
char *radiolist;
radiolist = _s_build_radiolist(
"\x03\x05\x00\x00\x00Button&1\0"
"\x03\x06\x00\x00\x00Button&2\0\0" );
_dbox_c_radio( 0, 1, radiolist, 0, NOFN );
This would define a radio button set with two buttons,
titled 'Button1' and 'Button2', and add it to dialogue
box 0 as control 1.
Button 'one' is positioned at x=3, y=5, relative to the
top left of the dialogue. These two bytes are followed
by three zero bytes for hotkey, alpha and greyness.
The text begins immediately after the greyness byte,
and may contain an ampersand to define hotkeys. The
text is terminated by a zero byte '\0', and then the
list continues with the definition for button 'two'.
This is positioned at x=3, y=6, immediately below the
first button. There are three zero bytes, followed by
the text 'Button&2' and a further '\0' to terminate
the string. The list is terminated by ending the final
string with a pair of zero bytes '\0\0', rather than
just one.
The initialitem parameter indicates which item is
checked, i.e. which button is pressed when the radio
button set is defined. The function parameter
specifies a hooked function which is called whenever
the button selection changes.
Text:
A text box has a title followed by a single line box in
which text can be entered and edited.
_dbox_c_text( dbox, control, xpos, ypos, size,
titletext, initialtext, function, filter );
Xpos and ypos position the first character of the
title. Size specifies the length of the text box,
although the text itself can be up to 1024 characters
long and is scrolled by Steph.
The title text is given in the normal way, with a
pointer to a string. The initial text that will appear
in the text window must be specified with a pointer to
a dynamically allocated string, i.e. memory allocated
by one of the malloc family of functions. This is
because Steph will need to 'realloc' this space when
the text is edited.
You can use strdup to create a dynamic copy of a string
constant:
_dbox_c_text( 0, 2, 1, 1, 16, "Ti&tle",
strdup("Initial text in the text box!" ),
NOFN, NOFN );
Function specifies a hooked function which is called
when the RETURN key is pressed in the text box.
Filter specifies a key filter function which can be
used to restrict the characters that can be entered
into the text box.
The filter function must read the character from the
global variable _dbox_spec.filter_key. If the key is
to be passed, the key should be left in the filter_key
variable. If the key is not to be passed by the filter
this variable should be set to zero.
If the filter function pointer is set to NOFN, a
default filter will be applied, which passes characters
in the range ASCII 32 to ASCII 126. Extended character
codes, such as cursor keys are not passed to the
filter.
List:
A list box displays a list of options. The user can
navigate through the list using mouse or keyboard.
Lists can be of either horizontal or vertical
orientation, with scroll bars.
_dbox_c_list( dbox, control, xpos, ypos, xsize,
ysize, fieldsize, orientation, titletext, list,
exitmode, select_function, highlight_function );
Xpos and ypos set the position of the first character
of the title text. The top left corner of the list box
is one character below this.
Xsize and ysize specify the internal dimensions of the
list box.
Fieldsize is used for horizontal lists where lists run
down the box until the bottom line is reached, and then
begin a new column to the right of the first. Field
size specifies the column width in characters. Note
that the list is displayed with a single character
margin to the left of the first column, and the last
character of each field is blanked to maintain
separation between columns. Therefore, fieldsize
should be one greater than the length of the longest
item possible in the list if you do not want items to
be truncated.
The orientation parameter should be set to DBL_HSCROLL
for a horizontal list or DBL_VSCROLL for a vertical
list.
Horizontal lists display a number of columns of text.
Each column contains a number of items corresponding to
the ysize of the box. The number of columns is then
dictated by the size of the list. A scroll bar at the
bottom of the box allows navigation through the list.
Vertical lists contain a single column, with a scroll
bar on the right hand edge.
Titletext is a pointer to a string which is displayed
as a title above the box. It may contain an ampersand
to specify a hotkey.
List is a pointer to the list to be displayed in the
box. This could be a pointer returned by the
_s_buildlist() function, as described elsewhere.
Exitmode is used as with button controls. The exitmode
parameter can be set to EXIT or NOEXIT and specifies
whether the dialogue should close when a selection is
made. ESCAPE is not valid for use with list boxes.
There are two functions that can be hooked to each
list. These are the select_function and
highlight_function. Each of these is a 'vfnptr' as
usual. The select function is called when a selection
is made. The highlight function is called when the
list box highlight moves to a new item in the list.
Combo box:
A combo box is similar to a vertical list, but displays
the current selection in a space more like a text box.
You can cycle through the list of options using the
cursor keys. The combo can be opened with the mouse by
pressing the open button, and a box, like a vertical
list pops up over the dialogue. The user can then
select from the list with the mouse or cursor keys.
_dbox_c_combo( dbox, control, xpos, ypos, xsize,
ysize, initial, titletext, list, exitflag,
select_function, highlight_function );
Xpos and ypos specify the position of the beginning of
the title text. This is followed by a space of xsize.
Xsize and ysize also specify the size of the box that
will pop up when the combo is opened.
The initial parameter specifies the item which is
initially displayed.
Titletext and list specify the title and contents of
the list, as for the list box above. select_function
and highlight_function operate in exactly the same way
as for the list box.
Reading and writing the data in a dialogue.
Your program will need to access the data stored in a
dialogue. The program may also need to change this
data, for example to change the contents of a list.
To do this you need to access structure members in
_dbox[dbox].control[cnum]
where dbox specifies the dialogue box, and cnum is the
control number in that dialogue box.
_dbox[dbox].control[cnum].iret is an integer that
stores integer return values from controls. It will be
referred to in the following simply as iret:
_dbox[dbox].control[cnum].iret
Buttons:
If a button has been pressed one or more times since
the dialogue was opened, then iret will be set to TRUE.
Otherwise, iret will be FALSE.
Check boxes:
If the box is checked, iret will be TRUE. If the box
is not checked, iret will be FALSE. The program can
change iret to change the data stored in the check
box.
Radio buttons:
Iret will be the number of the radio button that is
currently selected. The first button is zero, and they
are numbered in the order in which they were defined in
the list that was passed to _dbox_c_radio(). The
program can set iret to change the selected item.
Text boxes:
Iret is not used with text boxes. The text string is
stored in an area of dynamically allocated memory and a
pointer to that buffer is held in the variable
_dbox[dbox].control[control].bret .
You should never assume that this pointer remains
constant, since it may be changed by Steph even if the
text in the box has not been edited.
You can change the text by making this pointer point to
the new string. You should ensure that the pointer
points to dynamically allocated text, or the system is
liable to crash while editing. You may free() the old
text if it is no longer required.
List boxes:
List boxes use both iret and bret (see text boxes,
above). Iret stores the number of the currently
selected item in the list. It can be interrogated or
set by the program. The items in the list are numbered
beginning at zero.
A variable similar to iret is an integer (int) called
inf3 and is accessed in the same way:
_dbox[dbox].control[cnum].inf3 .
The inf3 variable stores the start position for the list:
A column number for horizontal lists, and an item number
for vertical lists. That is, it contains the column number
of the leftmost column, or the topmost item that is visible
in the list box.
Bret is a pointer to a dynamically allocated buffer
that contains a list such as one built by
_s_buildlist(). This defines the list that will
appear in the list box. You can change the list by
making this pointer point to a new list, remembering
to free() the old list if it is no longer required.
When you change bret to point to a new list, you should
ensure that the current selection remains within the
limits of the new list. For example, if the highlight
is on item five of a long list, and you then change the
list to one containing only four items, the selection
will be invalid.
It is a sensible precaution therefore to zero both the
iret and inf3 variables when a list changes, thus ensuring
that the highlight remains on a valid item. Use code such as:
/* change the list in control 4, dialogue 0 */
_dbox[0].control[4].bret = newlist;
_dbox[0].control[4].iret = 0;
_dbox[0].control[4].inf3 = 0;
Combo boxes:
These use iret and bret in an identical way to list
boxes, as described above.
The inf3 variable is used differently in a combo box and
should not be altered. As described below, a combo box
should not have it's contents changed while its dialogue
is open, so there is no need to change the starting item.
You should, however, reset the current item to zero when
changing the list in a combo box. For example:
/* change the contents of a combo box */
_dbox[0].control[8].bret = newlist;
_dbox[0].control[8].iret = 0;
Labels:
You can change the text displayed on a label control by
manipulating a variable called init. For example:
/* change a label */
_dbox[0].control[2].init = "New String!";
If the new string is shorter than the old one, you should
add a number of spaces to the end of the new string to
ensure that the old one is fully overwritten.
Frames:
Frames are not interactive so clearly the
values of iret and bret that they return are
meaningless.
Updating and redrawing controls.
If your program needs to change the data stored in a
control, it is simplest to do it while the dialogue box
is off the screen. There will however be a number of
occasions where the user's interaction with one control
will require the data in another to change, with the
dialogue box displayed on the screen all the time.
You can change a control by writing to the data variables
as described in the above section.
Steph cannot tell if data has been changed in this way,
so it is up to the user to control the redrawing of the
controls that have changed. The function
_db_draw_control() is used to do this:
_dbox_draw_control( dbox, control );
Where dbox specifies the dialogue box, and control
specifies the control that must be redrawn.
Greyness.
Sometimes you will want to make certain controls on a
dialogue unavailable. Greyness refers to the fact that
controls made unavailable in this way are drawn in grey
rather than the black ink used for active controls
(assuming the default colour scheme).
To change the greyness of a control you use the
function _dbox_grey():
_dbox_grey( dbox, control, radioitem, greyness );
Where dbox specifies the dialogue, and control the
number of the control to be changed. If the control is
a set of radio buttons, then the parameter radioitem
specifies the individual button to be changed. The
radioitem parameter is ignored if the control is not a
set of radio buttons.
The parameter greyness determines what the greyness of
the control will be set to. It should be set to either
GREY or NOTGREY.
If the dialogue is open when the greyness is changed,
then the relevant controls should be redrawn using the
_dbox_draw_control() function.
Overriding a control's exit mode.
Buttons, list boxes and combo boxes have an 'exit mode',
described above, which determines whether the dialogue will
remain open or close down when the button is pressed, or a
selection made from the list. Moving the highlight does not
constitute a selection being made from a list or combo box.
There are situations where you will want to override the
exit mode of a control. To take a simple example, imagine
an 'OK' button at the bottom of a dialogue. The user
presses this button when they are happy with the data in
the dialogue and want to proceed with the operation...
The user presses the 'OK' button, and if all is well, the
button's hook function performs the operation which is
required. The button's exitmode is EXIT, so the dialogue
closes.
Now suppose that the data in the dialogue is incorrect.
The 'OK' button's hook function detects this, and rather
than closing the dialogue it beeps and keeps the dialogue
open so that you can correct you mistake.
How is this done?
Steph uses a variable in the _dbox_spec global structure to
pass a return value from each control to the dialogue box
manager. The variable is called _ca_ret and can be
accessed using:
_dbox_spec._ca_ret = value;
or
variable = _dbox_spec._ca_ret;
When the 'select' function for a control (button, list or
combo) is being called, the _ca_ret variable has already
been set according to the exit mode of the control.
Possible values are:
_CA_ESC The exit mode is ESCAPE, and the
dialogue will close down restoring the
data to the on-entry state.
_CA_EXIT The exit mode is EXIT, and the dialogue
will close down leaving data intact.
_CA_NOEXIT The exit mode is NOEXIT. The dialogue
will not close down when the control is
'selected'.
The value is dependant entirely on the exit mode of the control.
If you want to override the default mode you simply write a new
value into the _ca_ret variable, depending on the behaviour you
want. The exit mode is not changed permanently. You should
write only one of the three constants listed above. Any other
value will give unpredictable results.
For example:
value = _dbox_spec._ca_ret;
/* value == _CA_EXIT, but we want to override that */
_dbox_spec._ca_ret = _CA_NOEXIT;
/* the dialogue will no longer close when the select
function returns. */
Dialogue box bars.
In order to improve the appearance of a dialogue, it is
sometimes useful to separate different parts with a
horizontal bar that runs across the box. An example is
the bar which separates the text and buttons on a query
box.
A dialogue can have up to four such bars. Their
positions on the dialogue are defined using the
function _dbox_setbars():
_dbox_setbars( dbox, bar1, ... );
This function takes a variable number of parameters.
The first is the number of the dialogue that the bars
will be added to.
The list of parameters that follow is a list of up to
four y positions, measured relative to the top of the
dialogue. For example:
_dbox_setbars( 0, 5, 10, 15, 17 );
would set horizontal bars on dialogue zero at five,
ten, fifteen and seventeen characters from the top of
the box.
If fewer than four bars are required, the list can be
terminated with the parameter _NO_BAR:
_dbox_setbars( 0, 5, _NO_BAR );
would set a single bar, five characters below the top
of dialogue zero.
Dependency.
When the user presses ESC in a dialogue box, or when a
button with the exitmode set to ESCAPE is pressed, the
data in the dialogue box is restored to the values that
were held on entry.
If, for example, a button on your first dialogue opens
a second dialogue, you may want the data in both
dialogues to be restored if ESC is pressed in the
first. In order to have this happen you can set your
second dialogue to be a dependant of the first:
_dbox_setdependants( dbox, dependant1, ... );
The first parameter is the number of the dialogue for
which dependants are to be defined. A dialogue may
have up to sixteen dependants. These are listed in
the variable length parameter list, with the constant
_NO_DEPENDANT used to terminate the list in a similar
way to the list of parameters passed to
_dbox_setbars().
Note that when the user presses ESC, the data is reset
only in those dialogues listed in the dependants list
for the current box. If a dependant of the current box
has dependants of its own, the data in these dialogues
will not be reset, unless they are also defined as
dependants of the first dialogue box.
The behaviour of List and Combo controls should be
explained more fully now. You will notice that the
contents of a list box are not reset by the user
pressing ESC. This is because the contents of a list
box are liable to change often whilst the dialogue is
open. The list stored in a combo box is assumed not to
change, at least while the dialogue is on the screen.
This means that Steph will restore the selection in a
combo when the user presses ESC.
To summarise:
List Box: List and selection are not reset by ESC.
List may be changed while dialogue is open.
You should zero iret and inf3 to move the
highlight to the start of the new list.
Combo Box: Selection is reset by ESC. List should
never be changed while dialogue is open.
You should zero iret when changing the
list at other times.
Dialogue box global keys.
Just as you define keyboard filter and action functions
for a window, so you can do for a dialogue box. This
filter will operate on all keystrokes made while that
dialogue is on the screen, regardless of which control
is active.
When a key is pressed it is examined by the current
control, which will act on it if appropriate. The key
is then passed to the global key filter, whether the
key was used by the control or not. It is therefore
possible for a keystroke to trigger two events, one in
the control and one in the global keystroke action
function. This is not normally desirable, so you
should ensure that the keys that your global key filter
will pass are not meaningful to the controls. A
typical use of the global key filter is to cause extra
information to be displayed when F1 (for help) is
pressed.
Global filter and action functions are attached to a
dialogue using:
_dbox_set_global_keys( dbox, filter, action );
Where dbox specifies the dialogue box, and filter and
action are pointers the the filter and action
functions.
The filter function is similar to the window filter
functions in that the keystroke information must be
read from two variables. Those variables are:
_dbox_spec.filter_key
_dbox_spec.filter_key2
Where filter_key contains either the ASCII code, or
zero, and filter_key2 contains either zero or the scan
code of the key. One of the variables will contain
information and the other will contain zero, depending
on whether the keystroke translates into an ASCII code
or not.
In order to pass the keystroke the function must leave
the values in these two variables intact. They will
remain there so that the action function can read them
too. If the key is not to be passed then both
variables should be set to zero.
Query Boxes.
A query box is a derivative of dialogue boxes. Queries
are not built in the same way as dialogue boxes before
they are used, instead the _query_box() function is
called which defines and opens the box.
A query box contains only text and buttons. For
example, the text may ask 'Do you want to continue?'
and the buttons will be 'Yes' and 'No'. A query box is
opened with:
button = _query_box( position, textlist,
buttonlist, helptext );
The position parameter can be either CENSCR or CENWIN,
to centre the query on the screen or on the currently
active window.
Textlist is a pointer to a list containing the lines of
text that will appear in the query. This can be
defined using _s_buildlist() in the same way as for
the text that appears in a flash box.
Buttonlist is a pointer to a similar list, but this one
contains a list of texts, with ampersands to define
hotkeys if necessary, which will appear as the row of
buttons below the text.
Helptext is a pointer to the string that appears on the
speed bar while the query is on the screen.
The function returns the number of the button that was
pressed. Numbering begins with zero, and increases
from left to right across the box, in the order that
the buttons were defined in the buttonlist. If the
query was exited with the ESC key, the function will
return the constant QB_NONE.
Using Dialogue Boxes.
Mouse.
Most users prefer to use the mouse to control dialogue
boxes. Control is fairly intuitive: Buttons can be
pressed by clicking the mouse over them. Radio buttons
can be selected and check boxes toggled in a similar
way. All controls are made active by clicking the
mouse over them.
Text boxes can be selected by clicking the mouse in the
text area: If the text box was the active control the
mouse will place the cursor within the text, if not,
the text box becomes active and the text is
highlighted.
A combo box can be opened by pressing the open button.
When open it behaves much like a list box. An open
combo box closes automatically when another control is
selected.
An item in a list box can be highlighted by clicking
over it. Double clicking, or 'selecting' is
considered a seperate event by Steph. The highlight
can be dragged by holding the mouse button down. The
list can be made to scroll by dragging the cursor
outside the list box. Scrolling can also be achieved
by clicking on the scroll bar or by dragging the scroll
bar blip.
Keyboard.
The controls in a dialogue box can be operated entirely
by the keyboard. Combo boxes can be used, but cannot
be popped open without a mouse. Toolbar buttons and
combo boxes, although derived from dialogue controls
cannot be activated without a mouse.
To navigate about the dialogue box, the TAB key is
used. This cycles through the controls in order,
activating each in turn. To cycle backwards the SHIFT-
TAB combination is used. Controls will only react to
the user when active. You can move straight to a
control by pressing the ALT key with the highlighted
hotkey for that control.
Buttons can be pressed by hitting either the RETURN key
or the space bar. Check boxes can be toggled by
pressing the space bar, and pressing RETURN has the
effect of closing down the dialogue.
The cursor keys are used to cycle through the options
in a set of radio buttons. Again, pressing return
closes down the dialogue.
Text boxes accept text when it is typed at the
keyboard. The insert or overtype mode can be toggled
with the INS key. Backspace and DEL delete the
character before or under the cursor respectively. The
cursor keys move the cursor through the text, scrolling
the box if necessary. Holding down the shift key when
moving the cursor will highlight a range of characters
which can then be deleted or typed over. HOME and END
keys move to the start or end of the text respectively.
The highlight is moved through list boxes with the
cursor keys, scrolling if necessary as it goes.
Pressing RETURN selects an item from the list.
Pressing an alphanumeric key will move the highlight to
the next item in the list which begins with that
character. HOME, END, PGUP and PGDN can be used to
move more rapidly through long lists.
Combo boxes behave just like vertical list boxes. When
a combo is closed only the highlighted item can be seen
in the window. If the box has been opened with the
mouse the whole list will be visible.
The ESC key can be pressed at any time to leave the
dialogue, restoring the data to the state it was when
the box was opened. Data is also restored in any
dependant dialogue boxes.
More things to do with windows.
Opening, closing, resizing etc.
Steph provides the programmer with the ability to open
and close windows from the application code. Windows
can also be resized, activated, etc.
When you need to open a new window, or close one, this
can be achieved from the application code:
_window_open( window, open );
Where window is the number of a previously built
window, and open is a constant which may be OPEN or
CLOSED, to specify what is to be done to the window in
question.
To change the active window, you use the function:
_window_make_active( window );
Where window should be the number of a window which is
currently open on the screen.
You can maximise or minimise a window from the
application using the functions:
_window_maximise( window );
_window_minimise();
Where window specifies the window to be maximised. If
a window is already maximised, the maximise function
will return having had no effect. The
_window_minimise() function takes no parameters, simply
minimising the window that is currently maximised, if
there is one.
To change the size of a window use the function:
_window_size( window, against, rows );
This function takes three parameters. Window specifies
the number of the window that is to be resized.
Attempting to size window zero (the main window) will
have no effect since this window expands to fill the
space left when all other windows have been drawn. The
rows parameter specifies the new size of the window.
The against parameter specifies the number of the
window from which lines will be removed or added to
balance the change in size of the window being resized
- the against window must be open on the screen at the
time the function is called.
The function checks to ensure that the new size will
fit on the screen, resizes the window and returns TRUE
to indicate success. If the requested size change
could not be accommodated, the function will return
FALSE. The function will also fail if a window is
currently maximised.
Redrawing and refreshing windows.
When you have finished opening, closing, and sizing
windows, you will notice that nothing has happened on
the screen. In order to redraw the windows you must
call the function:
_window_draw();
Which will redraw all the borders, titles, scroll bars
and controls. This function does not redraw the
contents of the windows, as this can sometimes take a
few moments and you may like to optimise the process by
refreshing only those parts of those windows that
require it.
You can redraw a window's contents with:
_window_refresh( window );
Or you can refresh all the visible windows using:
_window_refresh_all();
If you simply want to blank a window, leaving the
contents buffer intact, use the function:
_window_clear( window );
When only some lines on a window have changed, you can
optimise the refresh by using the function:
_window_lines_refresh( window, startline, endline,
dofixed );
Window is the number of the window to be refreshed, and
startline and endline specify the range of lines from
the contents buffer to be refreshed. The dofixed
parameter is useful if a window has a number of fixed
lines at the top, and it should be set to TRUE if those
lines are to be refreshed.
The window contents list.
The contents of a window are stored in a linked list.
Each element in the list describes one line of the
contents of the window. Each window is created with an
empty contents list.
The system maintains a pointer to the current 'line' in
the list. All operations act on the current line.
To insert a new line into the list, at the current
position use:
_wb_newline( window );
The window parameter is necessary to specify the list
that you wish to add to. Each window owns one list.
The new line is created empty, and is inserted into the
contents list at the current position.
Similarly, to remove the current line from the list use
the function:
_wb_delline( window );
If the line thus deleted contained a text, the text
will be deleted and the memory that it used will be
free'd.
Once a number of lines have been defined, you can move
between them using:
_wb_gotoline( window, linenumber );
Where window specifies the list belonging to a
particular window, and linenumber specifies the line.
The first line is line number zero.
To set the text stored in the current line, use:
_wb_settext( window, linetext );
Where linetext is a pointer to a text string, which
must be stored in dynamically allocated memory. The
strdup function can be used to make a dynamic copy of a
string.
The contents of the window contents list will be
displayed in the window when it is refreshed with one
of the _window_refresh() functions.
Steph allows a further piece of information to be
stored with each buffer line. These are called
endcodes, and take the form of int values which are
stored in the linked list. Endcodes can be put to any
use by the programmer: As a typical example, consider
a window that contains a text editor in which long
lines are 'word wrapped'. The editor will need to
distinguish between lines that have been wrapped, and
lines that end with a carriage return. It may also be
necessary to mark the last line in the document, or to
include formatting codes. If this or any other
information can be encoded into a single integer value,
it can be stored as an endcode.
Endcodes are set and read for the current line using
the functions _wb_setend and _wb_getend, as described
in the reference section below.
Note that the endcode information is not used by Steph,
so the value will have no effect on, for example, the
display of window contents on the screen. Endcodes are
provided merely as a means of attaching data to a
window buffer on a line-by-line basis, and their
implementation is left to the programmer.
Fixed lines.
Steph allows a number of lines from the beginning of
the contents list to be permanently displayed at the
top of a window, regardless of the line offset value
stored in the _window[].lineo variable. This is
similar to the feature which allows the top rows of
many spreadsheets to be locked - displaying column
headings at the top of the screen. The feature might
alternatively be used to provide a ruler line in a word
processor.
The _window_setfixed() function is used to set the
number of lines which are to be fixed at the top of a
particular window:
_window_setfixed( window, fixed_lines );
Suppose this call was made with fixed_lines equal to
three: The top three lines of the window, when
displayed, will show lines 0, 1, and 2 from the
contents list for that window. Normal display will
begin with the line specified by _window[].lineo, on
the fourth line of the window.
Notice that if, for example, the number of fixed lines
is three, and the line offset for the window is set to
zero, the first three lines from the contents list will
appear twice: Once in the fixed lines, and again
below, in the main body of the window. It is the
responsibility of the programmer to avoid such a
situation (by setting the line offset appropriately) if
this is deemed undesirable.
Window redraw modes and the redraw function.
The discussion above has assumed that windows are in
the standard mode. That is, they contain text with
constant foreground and background colours which is
defined in a linked list as described.
There are, in fact, four modes which can be used. The
behaviour of the window is different in each case.
Mode Description
WD_AUTO The standard mode as described above.
WD_COLOUR A mode allowing greater flexibility in the use
of colour.
WD_CLEAR A mode where the window is cleared but not
redrawn.
WD_USER A mode where the user has total redraw control.
Windows are set into one of these four modes using the
function:
_window_set_draw( window, drawmode, draw_func );
Where window is the number of the window whose draw
mode is to be changed, drawmode is one of the four
constants listed above, to specify the new mode for
that window, and draw_func is a 'vfnptr' pointer to a
function which will be called each time that window is
refreshed.
The draw_func function can contain code for redrawing
the window, or it may contain any other code that
should be run when the window is refreshed. The
draw_func function is always called after any built in
refresh operations which are applicable to the current
window mode.
The WD_AUTO mode.
AUTO mode is the default mode. Windows are
automatically placed into this mode when they are
built. The window contents are provided in the window
contents buffer as described previously, and the window
has fixed background and foreground colours.
Characters from the entire Extended ASCII character set
may be displayed. The draw_func function is called
when the window has been refreshed.
The WD_COLOUR mode.
This mode is identical to the AUTO mode, but allows
colour codes to be inserted into the lines. In the
absence of colour codes, the mode appears identical to
AUTO mode. The functions for manipulating colour codes
are described below. The draw_func function is called
when the window has been refreshed.
The WD_CLEAR mode.
This mode clears the window to the background colour
when refreshed, but does not attempt to display the
window contents. The draw_func function is called when
the window has been cleared, and is responsible for any
further display that is required.
The WD_AUTO mode.
This mode places the entire responsibility for
refreshing the window on the draw_func function. It is
particularly useful when running Steph in a graphics
mode. A discussion of graphics mode operation can be
found elsewhere.
Colouring functions for WD_COLOUR mode.
Steph provides a number of functions for the
manipulation of colour codes in the window contents
list.
Colours are specified as paper and ink colours for
individual character squares. There will be sixteen
foreground colours available, and either eight or
sixteen background colours. Where eight background
colours are available those numbered from 8 to 15 will
give flashing colours. Most video systems can be
switched to give either eight background colours plus
flashing colours, or sixteen steady colours.
To set the colours of a range of characters, use:
_wbcc_setcolour( window, sline, schar, eline,
echar, ink, paper );
Where window specifies the window whose contents are to
be coloured. Sline and schar specify the line and
character position on that line of the first character
to be coloured. Similarly eline and echar specify the
line and character position within that line of the
last character to be coloured. Ink and paper give the
foreground and background colours respectively.
If a character has not had its colour specifically set,
it will be displayed in the default colours for that
window.
To remove all colour codes from a line, use:
_wbcc_uncolour( window, line );
Which will restore the whole line to the default colour
scheme.
These two functions give control over the colours of
all characters in the contents list. Now, suppose a
window contains help text. The user clicks the mouse
on the window and you want to know if the click
corresponds to a word which has been highlighted as a
link to another subject. You can use the
_wbcc_getcolour function to determine the colours of a
particular character, and hence determine whether that
character is part of a highlighted word:
_wbcc_getcolour( window, line, qchar, ink,
paper );
In this call, window specifies the window in question,
and line and qchar are used to specify the line and
character position within that line for which colour
information is required. The ink and paper parameters
are pointers to short integer variables in which the
colour data is to be returned.
For example:
/* Read colours of character 0 on line 3 of window 0 */
short ink, paper;
_wbcc_getcolour( 0, 3, 0, &ink, &paper );
/* Ink and paper now contain the colour values */
Details of colour code storage in WD_COLOUR mode.
If you wish to have greater control of the colour
codes, you can insert the codes into the contents
buffers yourself.
A colour code consists of three bytes (characters) of
information. The first character is the colour code
character, which is defined in the constant _WD_CCODE.
The next two characters are character values between 1
and 16 which indicate the colours of ink and paper
respectively. Alternatively, if all three bytes of the
colour code are _WD_CCODE, this indicates the default
colours for the window.
Note that the colour values for ink and paper are in
the range 1 to 16, rather than 0 to 15, which is the
usual coding system. The colour value is simply
obtained by adding one to the colour number in the 0 to
15 range. This is done to avoid the occurrence of a
zero character which would be confused for the end of
the string.
Colour codes apply up to the end of the line, or until
another code is encountered. At the beginning of a new
line the default colours apply, until the first colour
code is found. Note that Steph makes a distinction
between default colours, set by either the beginning of
a line, or a colour code consisting of three _WD_CCODE
characters, and a colour scheme which may appear
identical, but which was set using a _WD_CCODE
character followed by two colour values.
The Speed Bar.
Text display on the speed bar.
The speed bar is the lowest line of the screen. It
automatically displays help text when menus or
dialogue boxes are in use.
At all other times the speed bar displays a predefined
string. This string is set using:
_speed_setbar( bartext );
where bartext is a pointer to the string to be
displayed. If any speed bar buttons are defined they
are painted over the text. Buttons appear only over
the default text, and are disabled when a help text or
message is displayed. If, at any time, you need to
display a message on the speed bar you can use:
_speed_text( bartext );
where bartext is a pointer to the text. You must
redraw the default text when your message is finished
with by calling the function:
_speed_show();
A structure member _speed_spec.isdef is used to
indicate whether the speed bar is displaying the
default text as displayed with _speed_show(), in which
case it will be set to TRUE. If the speed bar has been
displayed with _speed_text() or _speed_wipe() (see
later) then _speed_spec.isdef will be set to FALSE.
It may be necessary to attach a function to the speed
bar drawing operation. This is done using the
_set_speedbar_drawfn() function.
_speed_drawfn( function );
This is used to attach a standard 'vfnptr' function to
the event of redrawing the speed bar. It is called
when _speed_show() is used to redraw the speed bar.
Note that the Steph system makes calls to _speed_show()
in addition to those made by the user. You might
typically use this function to add extra information to
the speed bar, such as caps-lock, num-lock and overtype
status in a text editor.
The speed bar can be made to respond to mouse clicks:
_speed_clickfn( function );
This function is called when any mouse click is made on
the speed bar. If buttons are visible on the speed
bar, the clickfn is called only when the mouse is
clicked on the speed bar but not over one of those
buttons.
A further function _speed_wipebar() can be called to
clear the speed bar completely.
Adding buttons to the speed bar.
In addition to help messages and text, the speed bar
can be set up with a number of pressable buttons. When
buttons are defined they appear at the same time as the
default text, and are masked when help texts are shown.
The system maintains a list of the speed bar buttons,
numbered from 0 up to a maximum of 15. The buttons in
the list are displayed from left to right across the
speed bar.
Buttons are added to the list using:
_speed_button( button_number, text, chevron,
button_function ;
where button_number is the position in the list where
the button is to appear. The text parameter is a
pointer to a string containing the text that will be
displayed on the button. By setting chevron to TRUE
the button text will appear within <chevrons> or angled
brackets. Setting chevron to FALSE displays the button
without chevrons. A function is attached to the button
by passing a standard void function pointer in
button_function. This function will be called each
time the button is pressed.
When Steph comes to an undefined button, that is
treated as the end of the list. For this reason you
should ensure that all your buttons are numbered from
zero upwards, without gaps.
By default, buttons take the colour of the speed bar.
They can be given different colours using the function:
_speed_button_colour( button_number, ink, paper );
Where button_number identifies the button, and ink and
paper the colours to be used.
Buttons can be removed from the list using:
_speed_button_remove( button_number );
You should be aware that this function will leave an
undefined button, which will be treated as the end of
the list unless the position is filled.
Speed bar buttons are often used to indicate a keyboard
shortcut. For example, a button might appear as
<F1=Help> or <ALT=Menu>. The hook function for
<F1=Help> would activate a help system. A special
function is provided which can activate the menu
system. It opens the leftmost menu automatically:
_menu_go();
The Tool Bar.
Reserving a toolbar.
The tool bar is an area at the top of the screen, just
below the menu bar, to which controls can be attached.
The controls can be buttons, toggle buttons and combo
boxes. The tool bar is activated entirely by the mouse
- it cannot be operated by the keyboard alone.
Space for a toolbar is reserved before starting Steph
by calling the _toolbar_reserve() function.
_toolbar_reserve( number_of_lines );
which will reserve number_of_lines for the tool bar.
The number of lines can be as large as four. The tool
bars are then numbered from zero to three.
Controls on the speed bar.
The easiest way to use the toolbar is to attach
controls to it. Push buttons, toggle buttons and combo
boxes can all be attached.
Buttons are momentary devices, to which a function can
be attached. The function is called every time the
mouse is clicked over the button.
Toggles are similar to buttons, but like light
switches, they change from one state to the other each
time they are clicked. A different function can be
attached to the 'turning on' and 'turning off' of the
toggle.
Combo boxes are identical to those which can be
incorporated into dialogue boxes.
Up to sixteen controls can be defined, numbered from
zero to fifteen. They are defined using the following
functions:
_toolbar_set_button( control_number, bar,
position, text, function );
This sets control number control_number to a button.
The button will appear on the tool bar line specified
in the bar parameter, starting at the column specified
by position. The button text is stored in a string
pointed to by the text parameter, and function is a
pointer to a void function which will be called each
time the button is pressed.
_toolbar_set_toggle( control_number, bar,
position, text, initial, onfunction, offfunction );
This function sets control number control_number to a
toggle button. The toggle will appear on the tool bar
line specified by the bar parameter, at the column
specified by position. The toggle button text is
stored in a string pointed to by text.
The initial parameter should be set to ON or OFF to
indicate the initial state of the toggle. Onfunction
and offfunction are pointers to void functions.
Onfunction is called when the toggle switches from OFF
to ON, and offfunction is called when the toggle
switches from ON to OFF.
_toolbar_set_combo( control_number, bar, position,
xsize, ysize, text, list, initial, select_function );
This function sets control number control_number to a
combo box. Bar and position specify the position of
the control on the tool bar, as above. The xsize
parameter defines the width of the data area of the
combo, and also the width of the pop-up list. The
depth of the pop up list is defined by ysize. The
title of the box is stored in a string pointed to by
text.
The list parameter is a pointer to a list containing
the data from which the combo box selection is made.
This list is of the same format as a list created by a
call to _s_buildlist(). Initial specifies which item
in the list is to be the current selection when the
combo first appears.
A void function is attached to the combo using the
select_function pointer. This function is called when
a selection is made from the combo box. Note that
toolbar combo boxes do not support a highlight
function.
A tool bar control can be redrawn using:
_toolbar_draw_control( control_number );
Tool bar controls can be greyed as can dialogue box
controls. The _toolbar_grey function is used:
_toolbar_grey( control_number, greyness );
where control_number specifies the control to be
altered, and greyness is set to either GREY or NOTGREY.
Finally, a tool bar control can be removed using:
_toolbar_remove_control( control_number );
Displaying text on the toolbar.
Toolbar text can be also be displayed in a similar way
to the speed bar:
_toolbar_set( bar_number, text );
will set the specified line of the toolbar to display
the text in the string pointed to by text. A string
can be displayed on each reserved line in this manner.
The toolbar can be displayed or refreshed by calling:
_toolbar_draw();
Note that if any controls are defined they will be
painted over this text.
The entire toolbar area can be blanked by calling:
_toolbar_wipe();
Click and draw functions can be defined, which behave
in the same way as those for the speed bar. They are
defined using the functions:
_toolbar_clickfn( function );
_toolbar_drawfn( function );
Pop up menus.
In addition to the menus that appear on the menu bar at
the top of the screen, Steph provides pop up menus
that can be made to appear anywhere on the screen. Up
to four pop up menus can be defined. Like the main
menus they must be built before they can be used.
A pop up menu is built using the function:
_popmenu_build( pop_menu, item1, item2, ... )
The pop_menu parameter can be a number from 0 to 3, to
specify the pop up menu being built. The function then
takes a variable number of parameters which are the
menu item texts, terminated with a NULL.
For example:
_popmenu_build( 0, "&Frog", "&Goat", "&Marmot",
NULL );
Note that there is no menu title. All three texts in
the example are menu items. Notice that ampersands are
used to indicate the position of hotkeys. The pop up
menu items may also use the codes described under
_menu_build for adding check marks, horizontal bars,
etc. to the menus.
Functions are attached to the menu items using:
_popmenu_functions( pop_menu, func1, func2, ... );
Where the functions are 'vfnptr' pointers to functions.
There should be an identical number of functions as
there were menu items in the corresponding call to
_popmenu_build. A NOFN can be used as a place holder
if no function is to be attached to an item
Help text is added using:
_popmenu_helptext( pop_menu, text1, text2, ... );
A text must be supplied for each menu item. There
should be an identical number of texts as there were
menu items in the call to _popmenu_build. The constant
NOTEXT can be used if there is no help text for an
item.
When pop up menus have been defined, using the
functions above, they can be called up with:
_popmenu_go( pop_menu, row, col );
The menu is specified by its menu number, pop_menu.
The position on the screen is specified by the row and
column parameters. The menu will appear on the screen
allowing the user to make a selection with either the
mouse or the keyboard. When a selection is made the
menu will be removed from the screen and the function
attached to the selected item will be run.
Often, the pop up menus will be called up by clicking
the mouse. Often the right button is used. In this
case the menu should pop up under the mouse cursor:
_popmenu_atmouse( pop_menu );
This function assumes that the menu is being called up
after a mouse click over a window. It reads the select
position from the global variables and positions the
menu at that position. The function is designed to be
attached, either directly or indirectly, to a window's
'select' mouse action hook.
The _popmenu_toggle function can be attached to a menu
item in order to toggle the state of that items check
mark. The _popmenu_check function can also be used to
control the check mark. _popmenu_enable is used to
grey out items on a pop up menu. These functions
behave like their main menu counterparts, and are
described in the reference section of this manual.
Other Steph Facilities.
The Initialise Function.
Steph provides a hook that allows function calls to be
added after your call to the steph_go() function, but
before control is passed to the user. This hook can be
used when a piece of code should be run at the
beginning of program execution, but which needs to use
Steph's facilities. For example, you might like to show
a query asking 'Do you want instructions?'
The steph_go() function sets up the system with only
the main window, (zero) open. You can use the
initialise function to open other windows, or to set up
the contents of windows.
To add an initialise function use:
_set_initial_function( function );
Where function is a pointer to a standard hooked
function.
The Loop Functions.
The loop function facility provides a mechanism whereby
functions can be set up such that they are called
repeatedly while Steph is waiting for keyboard or mouse
activity. This allows a program to execute code that
is not attached to a specific window or menu item.
Steph calls loop functions many times a second
(depending on the speed of your computer). There are
three places where loop functions can be attached:
1) Waiting in the main input loop, where Steph waits
for input to the windows. This is the 'main' loop,
and it's loop function is the most important, as Steph
spends most of her spare time waiting in this loop.
2) While waiting for keyboard or mouse activity in the
menus.
3) While waiting for keyboard or mouse activity in
dialogue boxes.
A function is attached to the 'main loop' using the
function:
_loop_setfunction( func );
where func is a pointer to a void function that will be
called repeatedly whilst waiting in this loop. In most
situations this is the only loop function that will be
required.
Steph leaves the main loop whilst processing menu or
dialogue box activity, which means that the main loop
function is not being called when menus are active or
when a dialogue box is open on the screen. If it is
important that loop functions are executed in these
loops, you can attach them using the two following
functions:
_loop_menufunction( func );
_loop_dboxfunction( func );
You could attach the same function that is set for the
main loop function, or you could use a different
function in each case.
Notice that Steph's dialogue box sub-system is used
when a query box is active, or when a combo box is
active on the toolbar. The dialogue loop function will
be called in each of these cases.
Because the loop functions are called repeatedly, you
should ensure that they execute and terminate quickly;
otherwise the user may notice that the program's
responses to keyboard and mouse events become sluggish.
A typical use might be to provide an Auto-Save function
in a word processor. To do this you would set up a
loop function to measure the elapsed time since the
last save. In most cases, the specified time would not
have elapsed and the function would terminate
immediately. When the specified time had elapsed the
auto-save code would be invoked, and the timer reset.
Draggable dialogues.
Steph allows the user to drag dialogue boxes and query
boxes around the screen by clicking and dragging the
mouse on their title bars. The feature is, by default,
turned on for all dialogue boxes, and off for query
boxes.
The default behaviour can be overridden using the
following functions:
_dbox_dragdefault( dragmode, snapmode );
_dbox_dragdefault can be called at any time, and causes
subsequent calls to _dbox_build to build dialogue boxes
which have dragging enabled or disabled according to
the value of the dragmode parameter. Snapmode
determines whether dialogues will 'snap-back' to their
original positions after use, i.e. whether they will
recentre themselves on the screen next time they are
opened.
Once a dialogue has been built, the drag and snap
behaviour can be altered by calling the _dbox_setdrag
function:
_dbox_setdrag( dbox, dragmode, snapmode );
The dialogue box is identified by the dbox parameter,
and the drag and snap mode set as above.
Query boxes are not stored by the system, so the only
function provided is:
_query_dragdefault( dragmode );
The dragmode turns the drag feature on or off for all
subsequent query boxes. Note that there is no
snapmode. Since each query box is generated by Steph
when it is needed, they do not have a 'previous
position', so the snapmode parameter is not required.
All query boxes appear centred on the screen or a
window, as described elsewhere.
Working with Lists.
Lists are used by Steph to store a number of types of
data, includuing list box and combo box contents, flash
box texts, etc. A list can be thought of as a sequence
of strings, or 'items'. One item is dilimited from the
next by a null '\0' character, and the list is terminated
with a pair of null characters.
The _s_buildlist function has been used in previous
examples:
list = _s_buildlist( char *liststring );
Where list is a char* pointer to the list, and liststring
contains the contents with which the list is initialised.
For example:
char *my_list;
my_list = _s_buildlist( "One\0Two\0Three\0" );
Notice that each item is followed by a null character,
including the last one. When C adds a null to the end
of the string it has the two null characters described
above.
You can also create an empty list, which is useful prior
to using the insert and delete functions to create a list.
In this case the initialisation string is not required:
list = _s_buildemptylist( void );
Once a list has been created, it can be interrogated using
the following functions:
char *_s_list_item( char *list, unsigned number );
The function _s_list_item returns a pointer to the list
item specified by list, a pointer to the start of a
list, and number, the number of the item in the list,
where the first item is zero.
unsigned _s_list_count( char *list );
Given a pointer to the start of a list, _s_list_count
will return the number of items in the list.
Supposing you have a pointer to an item in a list, such
as that returned by _s_list_item, you can advance that
pointer to the next item in the list using the function:
char *_s_list_next( char *list );
The function will return NULL if there are no more items
in the list.
To add and remove items from a list, there are two functions:
char *_s_list_insert( char *list, char *item, unsigned at );
The _s_list_insert function takes a pointer to a list, and item,
which is a null terminated (i.e. ordinary) string to be inserted.
The position for the new item in the list is given by the value
in at. At can range from 0 to one greater than the number of items
in the list. It therefore follows that items can be added at the
beginning, the end, or at any position within the list. The
function returns a pointer to the list, since it may have been
moved in memory.
char *_s_list_delete( char *list, unsigned item );
The _s_list_delete function removes an item, specified by item
number, from the list. The value of item may range from 0 to the
number of items in the list. The function returns a pointer to
the updated list, which may have moved in memory.
Finally, there is a function to sort a list:
char *_s_list_sort( char *list );
The function sorts a list into ascending alphabetic order,
using the ASCII codes of the characters. A pointer is
returned since the modified list will have moved in memory.
Notice that the function _s_buildradiolist does not use a
standard format list, and cannot be manipulated with these
functions.
Memory allocation details.
Steph performs memory allocation using standard library
functions such as malloc and realloc. All the memory
used by Steph, including window contents and text mode
screen area saves has therefore to come from the base
640K of DOS memory. Application code attached to Steph
can use any memory that is available, so you may choose
to use the base 640K, or to use extended or virtual
memory, depending on your needs.
The 640K of base memory is often in short supply, and
if it is in heavy demand, it may run out. Fortunately,
Steph provides a mechanism for dealing with these
situations. The same mechanism can be used by
application code to display consistent behaviour in out
of memory situations.
The mem_handler function.
If a memory allocation fails, Steph calls a function
called the mem_handler. The default mem_handler
displays a flash box saying that the system has run out
of memory, and prompting the user to save and quit the
application. It makes no attempt to rectify the
problem, or free up extra memory. Clearly, there will
be many situations in which a more intelligent response
is required, and the mem_handler function must be
redefined.
Redefining mem_handler.
The mem_handler function must be a function of type:
void out_of_memory( void );
To attach a function to the mem_handler hook use:
_steph_spec.mem_handler = out_of_memory;
The action taken by the replacement function is up to
you. For example, you might use it to close down the
application tidily, or you may attempt to tidy up the
memory and free up enough space to re attempt the
allocation.
In the latter case, it may be useful to know how much
memory was requested. This information can be found in
the variable:
_steph_spec.mem_size;
Note that this variable will contain the total amount
of memory requested, even for a reallocation. For
example: If a block of memory if 200 bytes, and a
reallocation to 300 bytes fails, the value in mem_size
will be 300 bytes, rather than the extra 100 bytes.
Finally, the mem_handler function must return control
to Steph. The function simply returns in the normal
way, however, using the _steph_spec.mem_flag variable
it is possible to instruct Steph to re attempt the
allocation. This is demonstrated in the following
code:
void out_of_memory( void )
{
/* This is the mem_handler function */
printf( "Allocation of %d bytes failed.\n",
_steph_spec.mem_size );
/* Attempt to free some memory here */
...
if( we have free'd enough memory )
/* Instruct Steph to re attempt the allocation */
_steph_spec.mem_flag = TRUE;
else
/* Do not re attempt the allocation */
_steph_spec.mem_flag = FALSE;
return;
}
Notice that the mem_handler function does not attempt
to perform the allocation itself, but merely reports
back to Steph that it should be safe to do so. Should
the second attempt fail Steph will call mem_handler
again. Clearly, if the mem_handler keeps asking Steph
to retry, and Steph keeps failing to allocate the
memory, the system will be stuck in a loop. You may
like to implement a counter to limit the system to,
say, five retries.
Using the mem_handler mechanism from application
code.
Your application code can use the mem_handler mechanism
whenever a malloc or realloc type call is made. Code
similar to the following should be used to replace each
malloc call. Notice that the allocation is placed in a
loop which is repeated as long as the mem_handler
returns a TRUE in the mem_flag variable.
/* Attempt to allocate 123 bytes */
char * ptr;
do{
_steph_spec.mem_flag = FALSE;
_steph_spec.mem_size = 123;
ptr = (char *)malloc( 123 * sizeof(char) );
if( ptr == NULL )
(_steph_spec.mem_handler)();
}while( _steph_spec.mem_flag == TRUE );
if( ptr == NULL )
{
/* The allocation failed */
}
This is identical to the mechanism used by Steph herself
to allocate memory.
A neater way to allocate memory.
The description above shows you how to allocate memory
the hard way. There is a way which leads to neater code,
which is explained below. The reason for describing the
more complicated method first is to encourage you to
understand the way that the mem_handler system works.
Most of the time, when allocating memory, you are performing
a simple malloc, realloc or perhaps a strdup call. In each
of these three situations you can let Steph handle the
do-loop details for you, by providing a function to mimic the
functions in the C runtime library.
void *_s_malloc( unsigned size );
void *_s_realloc( void *buffer, unsigned size );
void *_s_strdup( char *string );
These three functions are designed to replace the similarly
named library functions.
Example, a similar allocation to the previous example:
/* Attempt to allocate 123 bytes */
char * ptr;
ptr = _s_malloc( 123 );
if( ptr == NULL )
{
/* The allocation failed */
}
By comparing the examples you will see that the _s_malloc call
has replaced the entire do-loop. The _s_realloc and _s_strdup
calls are used in exactly the same way. When you need to
perform an allocation using a function other than malloc, realloc
or strdup you will need to program a do-loop.
Customising Steph.
Steph is designed so that she is fully customisable.
You can change the colours, line and box drawing
characters, and many aspects of the spacing and
positioning of elements on the screen.
Selected system variables are listed in the reference
section.
USING STEPH IN GRAPHICS MODE.
Steph operates primarily in text screen modes. Each
character on the screen is identified by only two bytes
of data, a character and a colour. This means that even
80 by 50 character modes use only 8000 bytes of data,
and that whole screens can be output very quickly. By
comparison, a VGA graphics mode of 640 by 480 pixels,
in sixteen colours, uses 150K of video memory. The
amount of data that must be moved to and from the
screen is considerably greater, and makes hard work for
the computer.
Steph was designed to work in text modes and is
happiest when doing so.
Despite this, there may be occasions when you want to
use the Steph interface with a program that displays
pixel graphics. For these occasions Steph can be made
to run in one of two graphics modes, EGA and VGA. The
interface retains the familiar character based
appearance, but allows graphics to appear in the
windows. Although text based programs will work on the
most basic PC, graphics applications require an EGA
video system or greater (VGA, SVGA, XGA, etc).
Programming Steph to run in graphics modes requires a
little extra effort on your part. There are a number
of changes which should be made to a text mode program
to make it run in a graphics mode:
1) Set the computer into graphics mode.
2) Call _steph_initialise with the M_GRAPHIC parameter.
3) Set up screen save and restore functions.
4) Call _steph_setupgraphic().
5) Call _steph_go().
6) Include code to restore the screen mode in your
closedown code.
These steps are detailed below. The discussion is relevant
whatever compiler you are using, although these examples
assume Microsoft. A version of the save and restore functions
for Turbo C is provided in the file TC_GRAPH.C.
Set the computer into graphics mode.
The mode chosen should have the equivalent of 80
columns of text, and should be a sixteen colour mode
with a four bit plane organisation. Such modes include
modes 0x0E, 0x10, and 0x12, which are known as
_HRES16COLOR, _ERESCOLOR, and _VRES16COLOR in
Microsoft's GRAPH.H file. Steph has only been tested
in these modes, although other modes with the same
structure may work.
Call _steph_initialise with the M_GRAPHIC parameter.
This instructs Steph to prepare for graphics mode.
Set up screen save and restore functions.
When Steph opens a menu or dialogue box on the screen
the background is saved into memory so that it can be
restored when the menu or dialogue is finished with.
In text modes this is not a problem, since the amounts
of data are small - 8000 bytes at the very most. In a
graphics mode a large dialogue may need as much as 150K
of storage, and that could cause problems if you have
a lot of data in memory, or need a number of large
dialogues to appear over each other.
For this reason, Steph allows you to provide your own
functions for saving and restoring areas of the screen.
You can save data into conventional memory if you are
confident that there is enough space, or you may prefer
to use extended or virtual memory. Compression could
be applied to the data, or you could save it onto to
the hard disk.
When Steph calls your functions, the _pix_to_save
structure will contain relevant data. Elements .x1,
.y1, .x2 and .y2 contain the absolute co-ordinates of
the top left and bottom right corners of the
rectangular area to be saved. Your save function
should return a pointer of type (char *) in the
.data element. The same pointer will be placed in
.data by Steph before your restore function is called.
These two example functions use calls to Microsoft's
GRAPHICS.LIB to copy blocks of the screen into
conventional memory. You may like to adapt them to
your own needs:
void my_screen_save( void )
/* MICROSOFT ONLY, Turbo C users see TC_GRAPH.C */
{
long isize;
char _huge *store;
/* Find the size of the block to be saved from screen */
isize = _imagesize( _pix_to_save.x1, _pix_to_save.y1,
_pix_to_save.x2, _pix_to_save.y2 );
/* Halve the block size because we need to allocate it
in two byte blocks. */
isize = (isize+1)/2; /* one added incase size was odd */
/* Make space to store a pointer to the huge block that
we are about to allocate for the data... */
_pix_to_save.data = malloc( sizeof( char _huge * ) );
if( _pix_to_save.data == NULL )
return;
/* This allocates the data space.
(Element size must be power of two...) */
store = (char _huge *)_halloc( isize , 2);
if( store == (char _huge *)(NULL) )
return;
/* Store image (pixel) info using a call to
GRAPHICS.LIB */
_getimage( _pix_to_save.x1, _pix_to_save.y1,
_pix_to_save.x2, _pix_to_save.y2, store );
/* Store the pointer to the screen data in
the .data member */
/* _pix_to_save.data doesn't know that it is a
pointer to a pointer to a huge character, so it
must be cast. */
*((char _huge **)_pix_to_save.data ) = store;
}
void my_screen_restore( void )
/* MICROSOFT ONLY, Turbo C users see TC_GRAPH.C */
{
/* _pix_to_save.data doesn't know that it is a
pointer to a pointer to a huge character, so
it must be cast */
/* Restore the information onto the screen */
_putimage( _pix_to_save.x1, _pix_to_save.y1,
*((char _huge **)_pix_to_save.data), _GPSET );
/* Free the huge buffer that the data was in. */
_hfree( *((char _huge **)_pix_to_save.data) );
/* Free the pointer store. */
free( _pix_to_save.data );
}
Note that the _s_malloc function is NOT used for memory allocation
in these functions. Steph automatically surrounds her call to
your save function with a mem_handler do-loop. All your function
must do to signal an allocation error is to return NULL is .data.
In these examples, data is stored in conventional memory,
and a pointer is stored to a buffer which contains a pointer
to another buffer containing the data. If you choose to store
the data elsewhere, such as on disk, or in extended memory,
you must be able to identify the block by that first pointer
value. I would suggest that you allocate a relatively small
amount of memory to store (more extensive) details of your
saved block, and return a pointer to that block to Steph. Note
that a NULL pointer is used to indicate an allocation error.
Your restore function is responsible for deallocating
any memory used.
Call _steph_setupgraphic, giving details of the screen
size and pointers to the save and restore functions.
The _steph_setupgraphic function is called as follows:
_steph_setupgraphic( hsize, vsize, saveptr,
restoreptr )
Hsize and vsize are the horizontal and vertical size of
your screen mode in pixels. Values for _VRES16COLOR
would be 640 and 480 respectively.
Saveptr and restoreptr are vfnptr type pointers to your
block save and restore functions, described above.
Call _steph_go
Steph will operate in graphics mode. You will notice
that the screen updates are slower than in text modes.
If you are developing software for others to use,
please remember that their systems may not be as fast
as your development machine. You can reduce the time
taken to redraw the screen by keeping dialogues and
menus small, and refreshing only those parts of windows
that need it.
In order to include graphics in a window, you should
set the draw mode to WD_USER by calling
_window_set_draw. Set the draw function to be a
function which updates the window. Your draw function
is then responsible (along with other parts of your
application code which may draw in the window) for all
clearing and drawing operations on that window.
The size of the window can be determined with a call to
the function _window_get_gsize, as can be coded as
follows:
void my_draw_function( void )
{
/* create a _window_pix structure */
struct _window_pix pix_info;
/* fill the window pix structure.
This code assumes window zero */
pix_info = _window_get_gsize( 0 );
/* pix_info now contains elements as follows:
.xorigin
.yorigin
Absolute co-ordinates of top left corner of
window area.
.xsize
.ysize
Size of the window area in pixels.
*/
/* do your drawing here... */
}
Include code to restore the screen mode in your
closedown code.
A polite program always restores the video mode to the
one the system was in when the program was run!
REFERENCE.
User Functions.
This section lists the function prototypes for
functions that may be called by applications.
Functions not listed in this section are for internal
use by Steph, and are liable to change in later
versions.
Setup And Go Functions.
char _steph_initialise( char gmode );
Initialise Steph. This function should be called
before any of Steph's facilities are used. All the
functions listed in this manual require Steph to have
been initialised using this function.
gmode Normally M_TEXT. M_GRAPHIC to use
Steph in graphics modes.
Returns :
TRUE Success.
FALSE Failure The current screen mode was unsuitable.
(Screen mode must be 2, 3, or 7. Screens may have 25,
43 or 50 lines etc. )
void _steph_go( void );
Start the user interface, once menus, windows etc have
been set up. _steph_go() will return after displaying
an error message should you attempt to start the system
before the main window (window zero) has been built,
or if no menu items have been defined. An error is the
only circumstance under which the function will return,
in which case a message will have been displayed on the
screen. Once the system has started the _steph_go()
function never returns, and exit() must be called to
quit the application. The system variable
_steph_spec.steph_running is set to TRUE.
void _steph_closedown( void );
This function closes down Steph and tidies up the
system, ready to exit the program. The variable
_steph_spec.steph_running is reset to FALSE. The call
to _steph_closedown is usually followed by an exit()
in order to return to the operating system.
NOTE: This function closes down services vital to
Steph. The result of calling one of Steph's functions
is undefined after closedown, and doing so may cause an
immediate system crash or subsequent instability.
void _steph_version( char *version_string );
This function takes a pointer to a string and places in
it a string representing the version number of the library
being used. This string will never be greater than ten
characters including the \0 termination character, and
will be of the form "1.0b" where '1' is the major version
number, '0' is the minor version number, and 'b' is the
revision number.
version_string A pointer to a string (character array)
in which the version string will be
stored. A character array of ten elements
is suitable.
Window Build Functions.
int _window_build( unsigned win, unsigned posn,
unsigned startrows, char *title, vfnptr filter,
vfnptr keyaction, vfnptr mouseaction );
Build a window in memory.
win The window number, zero for the MAIN window.
posn The window position code. Window zero should have
WP_MAIN. Other windows may be WP_TOP or WP_BOT.
startrows The height of the window.
title Pointer to a string that appears on the top
border of the window as a title.
filter Pointer to the keyboard filter function for the
window.
keyaction Pointer to the keyboard action function.
mouseaction Reserved for future use.
Returns :
TRUE Success
FALSE Failure.
void _window_mouse_functions( unsigned win, vfnptr close,
vfnptr max, vfnptr min, vfnptr size, vfnptr vup, vfnptr vdown,
vfnptr vdrag, vfnptr vpup, vfnptr vpdown,
vfnptr hup, vfnptr hdown, vfnptr hdrag, vfnptr hpup,
vfnptr hpdown, vfnptr unselect, vfnptr select,
vfnptr activate );
This function attaches functions to the mouse event
hooks for the window.
win The window number.
close, max,... activate Function pointers as described
in text.
void _window_set_draw( unsigned win, char drawmode,
vfnptr drawfn );
Sets the drawing mode for the window, and also allows a
function to be attached to the redraw event.
win The window number
drawmode A constant for the draw mode required:
WD_AUTO, WD_COLOUR, WD_CLEAR or WD_USER. The draw
modes are described elsewhere in this manual.
drawfn A function called after each redraw event.
Menu Build Functions.
int _menu_build( unsigned menu, char *menutext, ... );
Create a menu in memory.
menu The menu number.
menutext A pointer to the menu title. Subsequent
parameters are pointers to menu item texts, the
list is terminated with a NULL pointer.
Returns :
TRUE Success
FALSE Failure.
void _menu_functions( unsigned menu, vfnptr afunc, ... );
Attach functions to the items in a previously built
menu.
menu The menu number.
afunc Pointer to the function attached to the first
menu item for the menu. There should be sufficient
parameters for each item in the menu. NOFN can be
used to indicate that there is no attached function.
void _menu_helptext( unsigned menu, char *maintext,
char *text, ... );
Sets the speed bar help text for the menu and menu
items.
menu The menu number.
maintext A pointer to the string to be displayed for
the menu title (on the menu bar).
text Pointer to string to be displayed for the first
menu item. There should be a further parameter for
each menu item. Use NOTEXT to indicate no text is
displayed.
Dialogue Box And Control Build Functions.
int _dbox_build( char dbox, char posn, char wide, char tall,
char numctrl, char *title, char *helptext );
Build a dialogue box in memory.
dbox The number of the dialogue box.
posn Positioning code, DB_CENWIN, DB_CENSCR or
DB_ABSPOS.
wide Width of the window in characters.
tall Height of the window in characters.
numctrl Number of controls that dialogue will contain
(maximum).
title Pointer to string to be displayed on the top edge
of the dialogue box's border.
helptext Pointer to string to be displayed on the speed
bar when the dialogue is open.
Returns :
TRUE Success.
FALSE Failure.
void _dbox_setbars( unsigned dbox, char bar1, ... );
Sets horizontal dividing bars to be drawn across
dialogue boxes.
dbox The number of the dialogue box.
bar1 The position of the bar, in characters from the
top of the box. Up to four bars can be listed, or the
list can be terminated with _NO_BAR.
void _dbox_setdependants( unsigned dbox, int dep_one, ... );
Sets up the list of dependants for a dialogue box.
This affects how data is restored when a dialogue is
ESCaped from.
dbox The number of the dialogue box to set dependants
for.
dep_one The number of the first dependant dialogue box.
The list may continue for up to sixteen dependants, or
can be terminated with a _NO_DEPENDANT.
void _dbox_setabspos( unsigned dbox, char xpos, char ypos );
Set the screen position for a dialogue box build as
DB_ABSPOS.
dbox The number of the dialogue box.
xpos X position in characters.
ypos Y position in characters.
void _dbox_c_label( unsigned dbox, unsigned cnum, char xpos,
char ypos, char *text );
Create a label on a dialogue box that has been built
previously.
dbox The number of the dialogue box.
cnum The number of the control.
xpos X position of start of label on the dialogue.
ypos Y position of start of label on the dialogue.
text Pointer to string containing the label text.
void _dbox_c_frame( unsigned dbox, unsigned cnum, char xpos,
char ypos, char xsize, char ysize, char *title );
Create a frame on a dialogue box that has been built
previously.
dbox The number of the dialogue box.
cnum The number of the control.
xpos X position of top left corner of frame on the
dialogue.
ypos Y position of top left corner of frame on the
dialogue.
xsize Width of frame in characters.
ysize Height of frame in characters.
title Pointer to a string to be displayed on the top
edge of the frame, or NULL for none.
void _dbox_c_button( unsigned dbox, unsigned cnum, char xpos,
char ypos, char size, char *text, char exitflag,
vfnptr function );
Create a button on a dialogue box that has been built
previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
xpos X position of start of button on the dialogue.
ypos Y position of start of button on the dialogue.
size The width of the button, between 'chevrons'.
text Pointer to string containing button text.
exitflag Determines how dialogue behaves when the
button is pressed. Can be EXIT to close dialogue
retaining data, ESCAPE to close dialogue restoring old
data, or NOEXIT to not exit.
function Pointer to a function to be called when the
button is pressed.
void _dbox_c_check( unsigned dbox, unsigned cnum, char xpos,
char ypos, char *text, int initval, vfnptr function );
Create a check box on a dialogue box that has been
built previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
xpos X position of start of title text on the
dialogue.
ypos Y position of start of title text on the
dialogue.
text Pointer to string containing title text.
initval TRUE for checked, or FALSE for not checked.
function Pointer to function called when check is
changed.
void _dbox_c_radio( unsigned dbox, unsigned cnum, char *text,
int initval, vfnptr function );
Create a radio button set on a dialogue box that has
been built previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
text Pointer to a buffer containing a radio_list. See
above.
initval The number of the radio item first selected.
function Pointer to function called when selection
changes.
void _dbox_c_text( unsigned dbox, unsigned cnum, char xpos,
char ypos, char xsize, char *title, char *text,
vfnptr function, vfnptr filter );
Create a text control on a dialogue box that has been
built previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
xpos X position of start of title text on dialogue.
ypos Y position of start of title text on dialogue.
xsize The number of characters contained in the text
box.
title Pointer to a string containing the control's
title.
text Pointer to a dynamic buffer containing the initial
text.
function Pointer to a function called when a new text
is entered.
filter Pointer to the text box filter function.
void _dbox_c_list( unsigned dbox, unsigned cnum, char xpos,
char ypos, char xsize, char ysize, char field,
unsigned scrolls, char *title, char *list, char exitflag,
vfnptr sfunction, vfnptr hfunction );
Create a list box on a dialogue box that has been built
previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
xpos X position of start of title text on dialogue.
ypos Y position of start of title text on dialogue.
xsize Width of box in characters.
ysize Height of box in characters.
field Column width in horizontal boxes.
scrolls DBL_HSCROLL for horizontal list, or DBL_VSCROLL
for vertical.
title Pointer to string containing title string.
list Pointer to the initial list.
exitflag EXIT to close dialogue when an item is
selected from the list, or NOEXIT otherwise. ESCAPE
is invalid.
sfunction Pointer to a function called when a selection
is made.
hfunction Pointer to a function called when the
highlight moves to a new item.
void _dbox_c_combo( unsigned dbox, unsigned cnum, char xpos,
char ypos, char xsize, char ysize, int initial, char *title,
char *list, char exitflag, vfnptr sfunction,
vfnptr hfunction );
Create a combo box on a dialogue box that has been
built previously.
dbox The number of the dialogue box.
cnum The number of the control, which determines
tabbing sequence.
xpos X position of start of title text on dialogue.
ypos Y position of start of title text on dialogue.
xsize Width of box in characters.
ysize Height of open box in characters.
initial Number of list item initially selected.
title Pointer to a string containing the combo title
text.
list Pointer to the list.
exitflag Exit flag, as for _dbox_c_list().
sfunction Pointer to function called when a selection
is made.
hfunction Pointer to function called when the highlight
is changed.
void _dbox_remove_control( unsigned dbox, unsigned cnum );
This function removes a control from a dialogue box.
Note that Steph treats a gap in the list of controls
as the end of the list.
dbox The number of the dialogue box.
cnum The number of the control to remove.
Miscellaneous Build Functions.
void _steph_initialfunction( vfnptr function );
Sets the initial function which will be called once
when Steph is started, as described above.
function A pointer to the function to be called.
void _loop_setfunction( vfnptr function );
Sets a pointer to a function which will be called
repeatedly whilst the system is idle and waiting for
keyboard or mouse input from the user in the main
input loop.
function A pointer to the loop function.
void _loop_menufunction( vfnptr function );
Sets a pointer to a function which will be called
repeatedly whilst the system is idle and waiting for
keyboard or mouse input from the user in the menu
input loop.
function A pointer to the loop function.
void _loop_dboxfunction( vfnptr function );
Sets a pointer to a function which will be called
repeatedly whilst the system is idle and waiting for
keyboard or mouse input from the user in one of the
dialogue input loop.
function A pointer to the loop function.
void _window_setsyskey( vfnptr filter, vfnptr action );
Sets the filter and action functions to handle
keystrokes that are valid in all windows, i.e. at the
'system' level.
filter Pointer to the filter function.
action Filter to the system key action function.
char *_s_buildradiolist( char *liststring );
This function allocates a block of memory and uses it
to store the specified radio button list.
liststring A pointer to a string, usually a constant,
containing the radio button list. The list
consists of a number of entries, each consisting
of five bytes of data, followed immediately by
the button label text as described above. A zero
'\n' character is used to separate entries, and
the final entry is followed by two zero characters
to indicate the end of the list.
Returns :
char * A pointer to the newly allocated buffer.
NULL Failure.
Dialogue, Flash and Query Boxes.
void _dbox_go( unsigned dbox );
Opens a dialogue box on the screen, and directs user
input to the dialogue.
dbox The number of the dialogue box to be opened.
void _dbox_draw_control( unsigned dbox, unsigned cnum );
Redraw the specified control on a dialogue box which is
open on the screen. This function should be used when
the contents of a dialogue are changed by the application
while the dialogue is visible.
dbox The number of the dialogue box.
cnum The number of the control to be redrawn.
void _dbox_grey( unsigned dbox, unsigned cnum, unsigned radio,
char grey );
Used to set the greyness (i.e. to activate or
deactivate) controls on a dialogue.
dbox The number of the dialogue.
cnum The number of the control to change.
radio If the control is a set of radio buttons this
parameter specifies the button number, otherwise it is
ignored.
grey TRUE to deactivate (grey) the control, FALSE to
activate it.
void _dbox_set_global_keys( unsigned dbox, vfnptr filter,
vfnptr action );
Sets up keyboard filter and action functions for a
dialogue box.
dbox The number of the dialogue box.
filter A pointer to the keyboard filter function.
action A pointer to the function called to process keys
that pass through the filter.
void _dbox_dragdefault( char drag, char snap );
Sets the default drag and snap-back for dialogue boxes
built subsequently.
drag TRUE to make dialogues draggable, else FALSE.
snap TRUE to make dialogues snap to their default
position when next opened after having been dragged.
FALSE for dialogues to reopen at the position to which
they were last dragged.
void _dbox_setdrag( unsigned dbox, char drag, char snap );
Used to alter the drag and snap-back characteristics of
individual dialogues after they have been built.
dbox The number of the dialogue box.
drag TRUE to make the dialogue draggable, else FALSE.
snap TRUE to make the dialogue snap to its default
position when next opened after having been dragged.
FALSE for the dialogue to reopen at the position to
which it was last dragged.
int _flash_box( char position, char *list );
Displays a flash box on the screen. The flash box
contents are defined in the call to the function. If a
flash box is already on the screen, it will be removed
and replaced.
position A constant, DB_CENSCR to centre the flash box
on the screen, or DB_CENWIN to centre the flash box on
the currently active window.
list A list, such as one built with build_list(), where
each item in the list is a line of text to be shown in
the flash box.
Returns :
TRUE Successful display.
FALSE The flash box could not be displayed.
void flash_remove( void );
Removes any flash box from the screen if one is
present.
int _query_box( unsigned dbox, char position, char *textlist,
char *buttonlist, char *helptext );
Displays a query box on the screen, and directs user
input to the query box.
dbox The number of a dbox, in which the query box is
built. The query box will replace any dialogue box
that was previously in that position.
position A constant, DB_CENSCR to centre the query box
on the screen, or DB_CENWIN to centre the query box
on the currently active window.
textlist A list, such as one built by build_list(),
where each item in the list is a line of text to be
shown in the query box.
buttonlist A list, such as one built by build_list(),
where each item in the list is a text to appear in
a button on the query box.
helptext A pointer to a string to be displayed on the
speed bar while the query box is on screen.
Returns :
int The number of the button pressed by the user.
QB_NONE No button was pressed.
QB_FAIL The query was not able to be displayed.
void _query_dragdefault( char drag );
Sets the drag mode for subsequent query boxes. Since
query boxes are generated when a call to _query_box()
is made, there is no need for a snap-back setting.
drag TRUE for query boxes to be draggable, else FALSE.
Menu Functions.
void _menu_go( void );
Starts up the menu system by opening the leftmost menu.
This function is intended to be attached to a speed bar
button.
void _menu_toggle( void );
This function toggles the state of checkable menu
items. It determines the menu and item number of the
checkable item automatically, and for this reason
should always be called from within a function attached
to a checkable menu item. The function can be attached
to the menu item's function hook directly if there is
no other function to be called.
char _menu_check( unsigned menu, unsigned item, char check );
Sets the check mark on a checkable menu item.
menu The menu number.
item The item number or zero for the entire menu.
check CHECKON to turn on the check mark or CHECKOFF to
turn it off.
Returns:
char The previous state of the check mark: CHECKON or
CHECKOFF. NOCHECK will be returned if this is
not a checkable item. CHECKERROR indicates that
the specified item did not exist.
char _menu_get_check( unsigned menu, unsigned item );
This function returns the state of the check mark for
the specified menu item.
menu The menu number.
item The item number or zero for the entire menu.
Returns:
char The state of the check mark: CHECKON or CHECKOFF.
NOCHECK will be returned if this is not a checkable
item. CHECKERROR indicates that the specified item
did not exist.
char _menu_enable( unsigned menu, unsigned item, char enable );
Used to control the greyness of a menu item. Entire
menus can also be disabled by specifying item zero.
menu The menu number.
item The item number or zero for the entire menu.
enable TRUE to enable the item, or FALSE to grey it
out.
Window Functions.
int _window_open( unsigned win, char open );
Opens or closes a window that has been built
previously.
win The number of the window to open or close.
open A constant, OPEN or CLOSE.
Returns :
TRUE Success
FALSE Failure.
char _window_close( unsigned win );
Close the specified window. It will be removed from
the screen at the next redraw, but will be retained in
memory.
win The number of a currently open window to be
closed.
Returns:
TRUE Success.
FALSE Failure.
int _window_make_active( unsigned win );
Change the currently active window. The window must be
open on the screen.
win The number of the window to be made active.
Returns :
TRUE Success.
FALSE Failure.
void _window_maximise( unsigned win );
Maximise the specified window such that it occupies the
whole of the work area.
win The number of the window to be maximised.
void _window_minimise( void );
Minimise the currently maximised window, returning the
windows to the arrangement that they were in before it
was maximised.
int _window_size( unsigned win, unsigned against,
unsigned newrows );
Adjust the size of a window.
win The number of the window to be resized.
against The window to add/remove lines from to satisfy
the request.
newrows The number of rows to be given to the window.
Returns :
TRUE Success.
FALSE Failure.
void _window_controls( unsigned win, unsigned char controls );
Sets the controls used on a window.
win The number of the window.
controls A byte specifying the controls. The byte can
be constructed using the bitwise OR operator and the
constants WC_CLOSE, WC_MAX, WC_MIN, WC_HSCROLL, and
WC_VSCROLL.
void _window_title( unsigned win, char *newtitle );
Sets the title to be displayed on the top border of a
window.
win The number of the window.
newtitle A pointer to a string to be used as title.
void _window_draw( void );
Redraws all window borders, as part of the process of
refreshing the screen. This should be called after
windows have been opened, closed resized etc.
void _window_drawscrollblips( void );
Redraws the scroll bar blips on all windows. The
_window[].vsblip and _window[].hsblip variables can be
set if necessary before the call.
void _window_set_vscroll_pc( unsigned win, int percent );
Sets the vertical scroll bar blip to a given
percentage.
win The number of the window to change.
percent Value between 0 and 100, to set blip position.
void _window_set_hscroll_pc( unsigned win, int percent );
As for _window_set_vscroll_pc(), but affecting the
horizontal scroll bar.
void _window_clear( unsigned win );
Clear the contents of a window to the paper colour.
The contents of the window are retained, but not
displayed.
win The number of the window to be cleared.
void _window_refresh( unsigned win );
Refresh a window, drawing the contents into the window.
This function operates only on a single, specified
window, in order to save time if you are able to
predict which windows are in need of a redraw.
win The number of the window to be refreshed.
void _window_refresh_lines( unsigned win, unsigned start,
unsigned end, char dofixed );
Refresh a window, drawing the contents into the window.
Only lines in the specified range will be refreshed,
possibly saving time over a full refresh. If there are
'fixed lines' in the window they can optionally be
refreshed.
win The number of the window to be refreshed.
start The start of a range of lines to be refreshed.
end The end of the range of lines to be refreshed.
dofixed TRUE to refresh fixed lines, or FALSE
otherwise.
void _window_refresh_all( void );
Refresh all windows by calling _window_refresh() for
each window currently open on the screen.
void _window_setfixed( unsigned win, char fixed );
Sets the number of fixed lines for a window.
win The window being addressed.
fixed The number of lines to be fixed. A value of zero
turns fixed lines off.
unsigned _window_above( unsigned win );
Find the window which is above another window on the
screen. The window above the top window is the lowest
one. The function ignores whether the windows are open
or closed.
win The window of which you want to know the number of
the window above.
Returns :
unsigned The number of the window immediately above.
unsigned _window_below( unsigned win );
Find the window which is below another window on the
screen. The window below the bottom window is the top
one. The function ignores whether the windows are open
or closed.
win The window that you want to know the number of the
window below.
Returns :
unsigned The number of the window immediately below.
unsigned _window_belowandopen( unsigned window );
unsigned _window_aboveandopen( unsigned window );
These two functions behave exactly as _window_above()
and _window_below(), but will only return the number
of windows that are currently open on the screen.
Window Buffer Functions.
int _wb_newline( unsigned win );
This function inserts a new line into a window's
contents buffer. The line is inserted after the
current line, and the new line is made the new current
line.
win The number of the window in whose buffer to add the
line.
Returns :
TRUE Success
FALSE Failure.
int _wb_delline( unsigned win );
This function deletes the current line from the
contents buffer.
win The number of the window in whose buffer to delete the
line.
Returns :
TRUE Success
FALSE Failure.
int _wb_gotoline( unsigned win, unsigned linenum );
Set the current line to a particular line in a window's
contents buffer.
win The number of the window in whose buffer to add the
line.
linenum The line which should be made the current line.
The first line in the buffer is zero.
Returns :
TRUE Success
FALSE Failure.
int _wb_settext( unsigned win, char *thetext );
Set the text contents of the current line in the
window's contents buffer.
win The number of the window in whose buffer to add the
line.
thetext A pointer to the text to be inserted into the
buffer at this line.
Returns :
TRUE Success.
FALSE Failure.
int _wb_setend( unsigned win, int endcode );
Set the endcode for the current line in the window's
contents buffer.
win The number of the window.
endcode The endcode value to be stored for the current
line.
Returns:
int The endcode value stored.
int _wb_getend( unsigned win );
Reads the endcode value stored with the current line in
the window's contents buffer.
win The number of the window.
Returns :
int The endcode stored with the current line.
Window Colour Code Functions.
These functions are used to control the use of colour
in windows that are in drawing mode WD_COLOUR. It
should be noted that a distinction is made between a
paper/ink combination and the default colours for a
window, even when they appear identical on the screen.
void _wbcc_setcolour( unsigned win, unsigned sline,
unsigned schar, unsigned eline, unsigned echar,
short ink, short paper );
This function is used to set the ink and paper colours
of a range of consecutive characters which may span a
number of lines. If the constant _WD_CCODE is used for
both ink and paper colours the characters will be set
to the default colours for that window.
win The window number.
sline The line number (in the contents buffer) of the
first character to be coloured.
schar The character number within the line, of the
first character to be coloured.
eline The line number (in the contents buffer) of the
last character to be coloured.
echar The character number within the line, of the last
character to be coloured.
ink The ink colour to be applied, or _WD_CCODE.
paper The paper colour to be applied, or _WD_CCODE.
void _wbcc_uncolour( unsigned win, unsigned line );
Removes all colour codes from a line in the window
contents buffer.
win The window number.
line The number of the line in the contents buffer.
void _wbcc_getcolour( unsigned win, unsigned line,
unsigned qchar, short *inks, short *papers );
This function returns the ink and paper colours of a
specified character in the window.
win The window number.
line The number of the line in the contents buffer.
qchar The position of the character in the line, for
which colours are required.
inks A pointer to a short variable in which the ink
colour will be returned.
papers A pointer to a short variable in which the paper
colour will be returned.
Speed Bar Functions.
void _speed_text( char *text );
Display a text on the speed bar.
text A pointer to the text string to be displayed.
void _speed_setbar( char *text );
Set the default speed bar text.
text A pointer to the text to be used as the default
speed bar text.
void _speed_show( void );
Redraw the default speed bar text.
void _speed_wipebar( void );
Blank the entire speed bar.
void _speed_drawfn( vfnptr func );
Set a function that is called whenever the default
speed bar is redrawn.
func A pointer to the function to be called when the
default speed bar is redraw.
void _speed_clickfn( vfnptr func );
Set a function that is called when the mouse is clicked
over the speed bar.
func A pointer to the function to be called when the
speed bar is clicked.
int _speed_button_set( unsigned button, char *text,
char chevron, vfnptr func );
Create a button to be displayed on the speed bar.
button The button number.
text The button text string.
chevron TRUE to display chevrons around the button
text, otherwise FALSE.
func The function that is called when the button is
clicked.
void _speed_button_colour( unsigned button, short ink,
short paper );
Sets the colours of a speed bar button.
button The button number.
ink The ink colour to be used.
paper The paper colour to be used.
void _speed_button_remove( unsigned button );
Removes a button from the speed bar button list. Note
that a space left in the list of buttons will be
treated as the end of the list.
button The number of the button to be removed.
Tool Bar Functions.
int _toolbar_reserve( char number );
Called before Steph is started to reserve space for the
tool bar.
number The number of tool bar lines to reserve.
void _toolbar_wipe( void );
Blanks the tool bar.
int _toolbar_set( char bar, char *text );
Sets the text which will be displayed on a particular
line of the tool bar.
bar The tool bar to place the text on.
text The string to be displayed.
void _toolbar_draw( void );
Redraw the toolbar, text, and controls.
void _toolbar_drawfn( vfnptr func );
Sets a function which is called when the tool bar is
redrawn.
func A pointer to the function.
void _toolbar_clickfn( vfnptr func );
Sets a function which is called when a mouse click is
made over the toolbar, but which is not picked up by
one of the controls.
func A pointer to the function.
int _toolbar_set_button( char control, char bar, char pos,
char *text, vfnptr func );
Creates a button control on the tool bar.
control The control number.
bar The toolbar line to be used.
pos The start column of the control.
text A string containing the button text.
func A function called when the button is clicked.
int _toolbar_set_toggle( char control, char bar, char pos,
char *text, char initial, vfnptr onfunc, vfnptr offfunc );
Creates a toggle button control on the tool bar.
control The control number.
bar The toolbar line to be used.
pos The start column of the control.
text A string containing the toggle button text.
initial The initial state of the toggle, ON or OFF.
onfunc A function called when the toggle is turned ON.
offfunc A function called when the toggle is turned
OFF.
int _toolbar_set_combo( char control, char bar, char pos,
char xsize, char ysize, char *text,
char *list, char initial, vfnptr sfunc );
Creates a combo box control on the tool bar.
control The control number.
bar The toolbar line to be used.
pos The start column of the control.
xsize The width of the data selection box and pop-up
list.
ysize The depth of the pop-up list.
text A string containing the combo title text.
list A pointer to the data list, such as created by
build_list().
initial The data item selected from the list
initially.
sfunc A function called when a selection is made from
the list.
void _toolbar_draw_control( char control );
Redraw the control onto the tool bar.
control The control to be redrawn.
void _toolbar_grey( char control, char grey );
Set the greyness of a control.
control The control to be altered.
grey The new greyness - GREY or NOTGREY.
void _toolbar_remove_control( char control );
Remove a control from the tool bar list.
control The control to be removed.
List functions.
char *_s_buildlist( char *liststring );
This function is used to build a list suitable for list
or combo box contents.
liststring A pointer to a string, usually a constant,
containing the list. The list contains a
number of entries, each of which is a text
terminated with a zero '\n' character. The
final entry is followed with two zero characters,
to indicate the end of the list.
Returns :
char * A pointer to the newly allocated buffer.
NULL Failure.
char *_s_buildemptylist( void );
This function is used to build an empty list suitable for list
or combo box contents.
Returns :
char * A pointer to the newly allocated buffer.
NULL Failure.
char *_s_list_item( char *list, unsigned item );
Finds the specified item within a list.
list A pointer to the start of the list.
item The number of the item to be found.
Returns:
char * A pointer to the item within the string.
NULL Failure.
unsigned _s_list_count( char *list );
Used to determine the number of entries in a list.
list A pointer to the start of the list.
Returns:
unsigned The number of items in the list.
char *_s_list_next( char *listptr );
Advances a pointer such that it points to the beginning
of the next item in the list.
listprt A pointer to an item in the list.
Returns:
char * A pointer to the beginning of the next item.
NULL Failure.
char *_s_list_insert( char *list, char *item, unsigned at );
Used to insert an item into a list at the specified position.
list A pointer to the start of the list.
item A pointer to a string to be inserted into the list.
at The position within the list, between zero and the
number of items in the list.
Returns:
char * A pointer to the modified list.
NULL Failure.
char *_s_list_delete( char *list, unsigned item );
This function removes an item from a list.
list A pointer to the start of the list.
item The number of the item to remove, between 0
and one less than the number of items in the list.
Returns:
char * A pointer to the modified list.
NULL Failure.
char *_s_list_sort( char *list );
Sorts a list into alphabetical order using the ASCII codes
of characters to determine order.
list A pointer to the start of the list.
Returns:
char * A pointer to the sorted list.
NULL Failure.
Mouse And Miscellaneous Functions.
void _mouse_on( void );
This function initialises the mouse driver and turns
the pointer on. The _mouse_vis function should be used
to control mouse visibility wherever possible.
void _mouse_off( void );
This function deactivates the mouse and hides the
pointer. The _mouse_vis function should be used to
control mouse visibility wherever possible.
void _mouse_vis( int vis );
This function is used to turn the mouse pointer on and
off.
vis A constant ON or OFF, for visible or invisible.
byte _mouse_nowbutton( void );
A function to return the current state of the mouse
buttons.
Returns :
byte A byte to indicate the button status. Bit zero is
set when the left button is pressed, bit one is set
when the right button is pressed, and bit two is set
when the centre button is pressed, if it is present and
supported by the mouse driver.
Macros of the form MBx_ISDOWN( status ) and MBx_ISUP(
status ) can be used to return a TRUE or FALSE
interpretation of the status byte where 'x' is either
L, R, or C to specify the button. Status is the status
byte as returned by _mouse_nowbutton().
int _s_insmode( int onoff );
Changes the keyboard insert, or overtype mode.
onoff A constant ON or OFF for insert or overtype.
Returns :
int The insert mode set by the function.
void _s_time_delay( float seconds );
Pause program execution for a specified period of time.
seconds The number of seconds to pause.
Cursor functions.
Steph provides all the functions necessary to control
the shape, position and visibility of the cursor.
These functions should be used instead of similar
functions provided by the compiler, which may not be
compatible with Steph.
void _s_settextposition( char row, char column );
Position the cursor.
row The row to position the cursor at. Row 1 is the
top.
column The column to position the cursor at. The
extreme left of the screen is column one.
short _s_gettextcursor( void );
Get the shape of the current cursor.
Returns :
short A value indicating the cursor shape, as returned
by BIOS interrupt 10h, function 03h.
void _s_settextcursor( short cursor );
Set the shape of the cursor.
cursor The high byte contains the start scan line for
the cursor in the range 0 to 15. The low byte
contains the finish scan line in the range 0 to 15.
void _s_displaycursor( int onoff );
Turns the cursor on or off.
onoff Either ON or OFF.
Keyboard functions.
These functions are available for reading data from the
keyboard. Note that Steph provides most of the
necessary keyboard handling, so these functions will
only be required in exceptional circumstances.
byte _s_shift_key_read( void );
Reads the state of the shift keys from the BIOS.
Returns :
byte A byte containing the shift key states, as
returned by BIOS interrupt 16h, function 02h.
void _s_key_read( char *k1, char *k2 );
Reads a keystroke from the BIOS.
k1 Pointer to char variable in which ASCII key code
will be returned
k2 Pointer to char variable in which the key scan code
will be returned.
For ASCII keys, k1 will contain the ASCII code of the
key, and k2 will be zero. For non-ASCII keys, such as
cursors, k1 will contain zero and k2 will contain the
scan code of the key.
char _s_wait_for_key( void );
Pause until a key is pressed. The function will return
immediately if there is a keystroke waiting in the
buffer.
Returns :
char The ASCII code of the key that was pressed, or
zero for a non-ASCII key.
char _s_key_for_me( void );
Used to determine whether there is a key waiting in the
keyboard buffer. The key is not removed from the
buffer.
Returns :
TRUE If a key is waiting.
FALSE There is no key waiting.
void _s_flush_keyboard( void );
Empties the keyboard buffer. This function can be
called before a call to _s_wait_for_key() to ensure
that _s_wait_for_key() doesn't return immediately.
Functions for Graphics Modes.
void _steph_setupgraphic( unsigned xpix, unsigned ypix,
vfnptr save, vfnptr restore );
Describes the screen size of the graphics mode to
Steph, and sets up the user defined screen save and
restore function pointers.
xpix Number of pixels across the screen.
ypix Number of pixels down the screen.
save Pointer to the user screen save function.
restore Pointer to the user screen restore function
struct _window_pix _window_get_gsize( unsigned win );
Returns the size of the usable area of the specified
window in pixels, and the position of the top left
corner in pixels from the top left corner of the
screen.
win The window number
Returns:
struct _window_pix A structure containing the size and
position of the window's usable area
in pixels. The structure is described
in the description of Steph's data
structures, below.
Popup Menu Functions.
Popup menus are very similar to Steph's menu bar menus.
The functions described below are similar to the
equivalent functions for the bar menus, with the
exception that popup menus do not have a menu name.
int _popmenu_build( unsigned menu, char *menutext, ... );
This function is used to build popup menus. There is
space for four popup menus to be built, numbered from
zero to three.
menu The popup menu number.
menutext A pointer to the text of the first menu item.
Subsequent parameters are pointers to further
menu item texts, the list is terminated with
a NULL pointer.
Returns :
TRUE Success
FALSE Failure.
void _popmenu_functions( unsigned menu, vfnptr afunc, ... );
Attach functions to the items in a previously built
popup menu.
menu The popup menu number.
afunc Pointer to the function attached to the first
menu item for the menu. There should be the correct
number of parameters for each item in the menu. NOFN
can be used to indicate that there is no attached
function.
void _popmenu_helptext( unsigned menu, char *text, ... );
Sets the speed bar help text for the popup menu items.
menu The popup menu number.
text Pointer to string to be displayed for the first
menu item. There should be a further parameter for
each menu item. Use NOTEXT to indicate no text is
displayed.
void _popmenu_go( unsigned menu, char row, char col );
Opens the specified menu for keyboard or mouse input.
The position of the menu on the screen can be chosen.
menu The popup menu number.
row The position of the menu in character rows.
col The position of the menu in character columns.
void _popmenu_atmouse( unsigned menu );
This function opens the specified menu at the most
recent mouse select position. That is, the position at
which the mouse was last clicked over the active
window. The menu can be made to appear with either top
left or top right corner under the mouse pointer
according to the value in the global variable
_menu_spec.pop_left. The function is intended to be
called from within the function attached to a window's
mouse select hook.
char _popmenu_enable( unsigned menu, unsigned item,
char enable );
void _popmenu_toggle( void );
char _popmenu_check( unsigned menu, unsigned item, char
check );
char _popmenu_get_check( unsigned menu, unsigned item );
These four functions are identical in operation to the
similarly named _menu functions. The exception is that
since popup menus have no item 0 this value cannot be
used in a call to _popmenu_enable.
Selected System Variables.
This reference section lists selected members from the
various Steph data structures, that may be of interest.
Variables not listed here should not be accessed, as
they are liable to change in later versions of Steph.
The ordering of variables in these lists may differ
from the order of variables in memory.
Some variables are marked read-only. These are
variables that are maintained by Steph, but may be of
interest to the application programmer. The read-only
status is not enforced, that is, you could write values
into these variables, but to do so would make Steph
unstable, and could cause a system crash.
The other variables are marked as initialise-only.
These variables define the appearance of Steph, and
should be set up after the call to steph_initialise(),
which sets up default values, and before the call to
steph_go(). Attempting to change these variables while
Steph is active will at best cause inconsistency in the
appearance of the system, and at worst, cause a system
crash.
Default values for INIT variables are in brackets ().
Where colour default values differ according to
graphics adapter, they are shown as (colour, mono).
General system variables.
The _steph_spec structure stores information about the
general Steph system:
_steph_spec.
char steph_running R/O Set to TRUE after steph_go() and
reset to false after
_steph_closedown().
int mode R/O Graphics adapter type, _COLOUR or
_MDAHERC
char gmode R/O Screen mode, _TEXT or M_GRAPHIC.
unsigned row, col R/O Size of the screen in characters
short cursor INIT Cursor shape for insert
mode (0x0707)
short otcursor INIT Cursor shape for overtype
mode (0x0007)
vfnptr mem_handler INIT Pointer to function called when
memory allocation fails.
char mem_flag Usually FALSE. The mem_handler function
should set it to TRUE to indicate
that the application should re attempt
the allocation.
uns. long mem_size Set to the number of bytes
requested by a failed allocation, so that
the mem_handler can attempt to free a
suitable block. May contain zero if the
block size could not be determined.
char * nomemlist INIT Pointer to a list of texts which
are displayed by the default mem_handler
function. May also be used by alternative
mem_handler functions.
Window variables.
The _window_spec structure stores information about
general window appearance and behaviour:
_window_spec.
unsigned active R/O Which window is active now?
int maximise R/O Number of window that is maximised
now, or -1 for none.
int lastbuilt R/O The last window built.
unsigned wincount R/O Number of windows built.
unsigned ttop R/O The toppest top window.
unsigned btop R/O The lowest top window.
unsigned tbottom R/O The toppest bottom window.
unsigned bbottom R/O The lowest bottom window.
char control_gap INIT The number of characters between
the left border and the close control,
and between the min/max controls and the
right border. (1)
char title_gap INIT Number of blank chars around window
titles. (1)
char sbinhib INIT Turn off scroll bars when a window is
less than this number of rows. (4)
short border_paper INIT Border background colour. (1,0)
short border_ink INIT Border foreground colour. (7)
short title_hilite INIT Active window title text colour. (0)
short title_ink INIT Inactive window title text and
active window title background colour. (7)
short title_paper INIT Inactive title background colour. (1,0)
short scroll_paper INIT Scroll bar background colour. (7)
short scroll_ink INIT Scroll bar foreground colour. (0)
short drag_ink INIT Title bar foreground during resize. (8)
short drag_paper INIT Title bar background during resize. (0)
char border[23] INIT Window border characters (see notes.)
char key1 R/O ASCII code store used for window/global
filter functions.
char key2 R/O Scan code store used for window/global
filter functions.
byte mousecode INIT Mouse button events recognised by a
window. (M_ANYPRESS)
byte mousecontrol INIT Subset of mousecode. Mouse button events
that activate window controls. (M_LEFTP)
unsigned last_action_window R/O Number of window on which last mouse
action occurred.
byte last_action_code R/O Type of action that occurred,
e.g WR_CLOSE, WR_SIZE.
byte last_mouse_button R/O Which mouse button caused the action.
int scrinfo R/O Scroll bar percentage after a drag
char selectx R/O X position of mouse when a click has
been made over a window.
char selecty R/O Y position of mouse when a click has
been made over a window.
The _window_spec.border[] array stores the characters
used to draw window borders, controls etc. A number of
macros provide access to the data.
Macro Description
W_TOPLEFT Top left border corner.
W_TOPRIGHT Top right border corner.
W_BOTLEFT Bottom left border corner.
W_BOTRIGHT Bottom right border corner.
W_TOP Top edge of border.
W_BOTTOM Bottom edge of border.
W_LEFT Left hand edge of border.
W_RIGHT Right hand edge of border.
W_CTRLLEFT The character that appears to the left of
top edge controls.
W_CTRLRIGHT The character that appears to the right of
top edge controls.
W_MAX The maximise control.
W_MIN The minimise control.
W_CLOSE The close control.
W_TOPL2 Top left border for a window which is not
toppest top.
W_TOPR2 Top right border for a window which is not
toppest top.
W_SCROLL The scroll bar background.
W_SCRUP Vertical scroll up arrow.
W_SCRDOWN Vertical scroll down arrow.
W_SCRLEFT Horizontal scroll left arrow.
W_SCRRIGHT Horizontal scroll right arrow.
W_SCRBLIP The scroll bar blip.
For example, to change the scroll bar blip to the
letter 'B', use:
W_SCRBLIP = 'B';
Or to find out what the close button is like:
variable = W_CLOSE;
The _window[] array stores information about individual
windows:
_window[].
char type R/O Position: main, top or bottom.
char numrows R/O Total size of the window in rows.
char usetop R/O First usable line inside the window.
char usebottom R/O Last usable line inside the window.
char isopen R/O Is the window open?
char controls R/O Window controls.
bit0 close
1 max
2 min
3 vscroll
4 hscroll
5 reserved
6 unused
7 unused
char vsblip User Character position of vertical
scroll blip
char hsblip User Character position of horizontal
scroll blip
short paper INIT Window contents paper colour (1,0)
short ink INIT Window contents ink colour (7)
unsigned blines R/O Number of lines in the contents
buffer.
unsigned current_line R/O The current line in the contents buffer.
char fix_lines R/O The number of fixed lines at the top.
short fix_ink INIT Fixed lines foreground colour. (0)
short fix_paper INIT Fixed lines background colour. (7)
unsigned lineo User Line offset, i.e. start display of
window contents buffer on this line.
unsigned charo User Character offset. Start display of
window contents buffer at this character.
char drawmode INIT The window drawing mode. (WD_AUTO)
vfnptr drawfn INIT The window drawing function. (NOFN)
Menu variables.
The _menu_spec structure stores information about the
menuing system.
_menu_spec.
unsigned lastbuilt R/O The last menu built.
int lastmenuselect R/O The last menu selection:
Menu number.
int lastitemselect R/O The last menu selection:
Item number.
short bar_ink INIT Menu bar ink. (0)
short bar_paper INIT Menu bar paper. (7)
short bar_hotkey INIT Menu bar hotkey ink. (15)
short bar_disabled INIT Menu bar grey item ink. (8,0)
short body_ink INIT Menu body ink. (0)
short body_paper INIT Menu body paper. (7)
short body_hotkey INIT Menu body hotkey ink. (15)
short body_disabled INIT Menu body grey item ink. (8,0)
char body_space INIT The space between menu item text
and the menu border. (1)
char body_offset INIT The menu body is shifted to the
right by this number of characters. (2)
char bar_space INIT Space between items on menu bar. (2)
char bar_hilite_edge INIT Overlaps of highlight past
the end of the text on the menu bar. (1)
char shadow_below INIT Size of shadow below menu. (1)
char shadow_right INIT Size of shadow to right of menu. (2)
char shadow_ink INIT Colour of ink in shadow. (8,0)
char shadow_paper INIT Colour of paper in shadow. (0)
char border[14] INIT Menu drawing characters (see notes.)
unsigned lastpopbuilt R/O The last popup menu built.
int lastpopmenuselect R/O The last popup menu selection:
Menu number.
int lastpopitemselect R/O The last popup menu selection:
Item number.
char popmenu R/O Set TRUE when popup menus are
active.
char pop_left INIT TRUE for _popmenu_at menus to appear
with mouse over top left corner.
FALSE for menus to appear with mouse over
top right corner. (FALSE)
The _menu_spec.border[] array stores the characters
used to draw window borders, controls etc. A number of
macros provide access to the data. See the examples for
_window_spec.border, above.
Macro Description
M_TOPLEFT Top left corner of the menu box border.
M_TOPRIGHT Top right corner of the menu box border.
M_BOTLEFT Bottom left corner of menu box border.
M_BOTRIGHT Bottom right corner of menu box border.
M_TOP Top edge of menu box.
M_BOTTOM Bottom edge of menu box.
M_LEFT Left hand edge of menu box.
M_RIGHT Right hand edge of menu box.
M_CROSSLEFT Cross bar meets left hand edge.
M_CROSSRIGHT Cross bar meets right hand edge.
M_CROSS Horizontal cross bar.
M_BLANKGAP White space surrounding item text.
M_CHECK Mark placed against checked menu items.
Dialogue box, query and flash box variables.
The _dbox_spec structure stores information about the
appearance of dialogue boxes.
_dbox_spec.
unsigned active R/O The number of the currently active
dialogue.
char border[32] INIT Dialogue drawing characters (see notes.)
short ink INIT Dialogue ink colour. (0)
short hotkey INIT Dialogue hotkey ink colour. (15)
short paper INIT Dialogue paper colour. (7)
short shadow_ink INIT Dialogue shadow ink colour. (8,0)
short shadow_paper INIT Dialogue shadow paper colour. (0)
short grey INIT Colour of greyed controls. (8,0)
char lift INIT Dialogues are lifted by this many
characters to improve appearance. (1)
float scrollsecs INIT Seconds to pause when scrolling
lists. (0.2)
float dclick INIT Double click time delay in seconds. (0.2)
char shadow_right INIT Size of shadow to right of dialogue. (2)
char shadow_below INIT Size of shadow below dialogue. (1)
char lbox_eofield INIT Number of blank characters at
end of text fields in horizontal lists.
unsigned char filter_key ASCII code key store for text
control filters.
unsigned char filter_key2 Scan code key store for text
control filters.
char _ca_ret Used for passing the return code from
a dialogue's controls. Can be manipulated
to alter the exit mode of a control.
short flash_ink INIT Ink colour for flash boxes. (0)
short flash_paper INIT Paper colour for flash boxes. (7)
char flash_vgap INIT Space above and below text lines
in flash boxes. (1)
char flash_hgap INIT Space to left and right of text in
flash boxes. (2)
char query_button_gap INIT Space between text & buttons
in query boxes.
(QB_BAR) - Indicates that a horizontal
bar is used.
char query_button_space INIT Space between button text & chevrons. (1)
char query_button_spacing INIT Space between adjacent chevrons. (3)
char query_bar_gap INIT Space above & below horizontal bar. (1)
There are two useful variables in the _dbctrl
structure:
_dbox[].control[].
int iret Integer return from control
char * bret Character pointer return from control
These are accessed as follows:
_dbox[number].control[control_number].iret
_dbox[number].control[control_number].bret
This was described in the discussion of dialogue boxes
earlier.
The _dbox_spec.border[] array stores the characters
used to draw dialogue boxes and controls. A number of
macros provide access to the data. See the examples
for _window_spec.border, above.
Macro Description
_DB_TOPLEFT Top left hand corner of the border.
_DB_TOP Top edge of the border.
_DB_TOPRIGHT Top right hand corner of the border.
_DB_LEFT Left hand edge of the border.
_DB_PAGE White space, dialogue background.
_DB_RIGHT Right hand edge of border.
_DB_BOTLEFT Bottom left hand corner of border.
_DB_BOT Bottom edge of border.
_DB_BOTRIGHT Bottom right hand corner of border.
_DB_BUTTONL Left hand 'chevron' on a button.
_DB_BUTTONR Right hand 'chevron' on a button.
_DB_CHECKL Left hand 'bracket' on a check box.
_DB_CHECK Check mark for a check box.
_DB_UNCHECK Shown in a check box that is not checked.
_DB_CHECKR Right hand 'bracket' on a check box.
_DB_RADIOL Left hand 'bracket' on a radio button.
_DB_RADIO Shown in the radio button that is selected.
_DB_RADIOR Right hand 'bracket' on a radio button.
_DB_TEXTL Left hand 'bracket' on a text box.
_DB_TEXT Unused space in text box.
_DB_TEXTR Right hand 'bracket' on text box.
_DB_SCROLL Scroll bar background.
_DB_LSCROLL Left arrow on horizontal scroll bar.
_DB_RSCROLL Right arrow on horizontal scroll bar.
_DB_USCROLL Up arrow on vertical scroll bar.
_DB_DSCROLL Down arrow on vertical scroll bar.
_DB_SCRBLIP Scroll bar blip.
_DB_BARL Horizontal bar meets left border.
_DB_BAR Horizontal bar.
_DB_BARR Horizontal bar meets right border.
_DB_COMBO Combo box open button.
Speed bar variables.
The structure _speed_spec contains information on the
speed bar.
_speed_spec.
short paper INIT Speed bar paper colour. (7)
short ink INIT Speed bar ink colour. (0)
char textindent INIT Speed bar text indent at left edge. (1)
char isdef R/O Set to TRUE when default text is shown.
char maxlen INIT Display no more that this number of
chars. (80)
char border[4] INIT Button drawing characters. (See notes.)
char button_indent INIT Position of first button. (1)
char button_space INIT Position between text and chevron. (0)
char button_spacing INIT Space between buttons on bar. (1)
The _speed_spec.border[] array stores the characters
used to draw speed bar buttons. A number of macros
provide access to the data. See the examples for
_window_spec.border, above.
Macro Description
_SB_BUTTONL Left hand edge of a speed bar button.
_SB_SPACE Space between edge of button and text.
_SB_BUTTONR Right hand edge of a speed bar button.
Tool bar variables.
The structure _tool_spec holds information about the
toolbars.
_tool_spec.
short paper INIT Paper colour for the toolbar. (7,4)
short ink INIT Ink colour for text and controls. (0,7)
short grey INIT Colour of greyed controls. (0)
char nlines R/O The number of toolbar lines used.
char textindent INIT Indent of text lines on
toolbar. (2)
There is a useful variable in the _tb_control
structure:
_tb_control[].
int iret Integer return from a toolbar control.
This variable stores the state of a toggle button
control, or the selected item in a combo box control.
It is accessed as follows:
_tb_control[control_number].iret
as described in the discussion of toolbar controls.
Graphics mode variables.
The structure __gminfo holds information about the
graphics screen mode. Note the double leading
underscore in the name.
__gminfo.
char _far * font_table R/O A pointer to the font used
for text display.
char * vbuf R/O A pointer to the video display mimic.
This is an area of memory arranged
in the same way as text mode video
memory. It should not be written to,
and this will have no effect on the
display. It may be read to determine
the character at a certain position
on the screen.
unsigned gx R/O Screen width in pixels.
unsigned gy R/O Screen height in pixels.
char xchar R/O Character box width in pixels.
char ychar R/O Character box height in pixels.
Structures of type _window_pix are returned by the
_window_gsize function to describe the size and
position of windows when in graphics screen modes.
unsigned xorigin R/O The absolute x position of the top
left corner of the window measured from
the left of the screen.
unsigned yorigin R/O The absolute y position of the top
left corner of the window measured from
the top of the screen.
unsigned xsize R/O The width of the window in pixels.
unsigned ysize R/O The height of the window in pixels.
The _pix_to_save structure is used for communication
between the Steph system and the screen save and
restore functions.
_pix_to_save.
unsigned x1 R/O X co-ordinate in pixels of top left
corner of area to be saved.
unsigned y1 R/O Y co-ordinate in pixels of top left
corner of area to be saved.
unsigned x2 R/O X co-ordinate in pixels of bottom right
corner of area to be saved.
unsigned y2 R/O Y co-ordinate in pixels of bottom right
corner of area to be saved.
char _huge * data Pointer to the data block into which
screen data has been saved or from which
it must be restored.